MASM Исправление 64-битного усечения в DLL - PullRequest
13 голосов
/ 16 февраля 2012

Я работаю с Adobe Flash ocx, загружая его в свою C ++ программу. Предполагается, что ocx будет 64-битным, но по какой-то причине возникают проблемы при компиляции с платформой x64. Я прочитал об этом и обнаружил, что вполне вероятно, что какая-то функция получает DWORD userData вместо void* userData через некоторую структуру, а затем приводит ее к указателю объекта. Это работает нормально в 32-битной среде, но вылетает в 64-битной.

Разборка вызовов функций внутри ocx, вызывающих сбой, состоит из следующих строк:

mov         ecx,r8d 

Первая операция копирует только младшие 32 бита из R8D в ECX (ECX 32-битный).

cmp         dword ptr [rcx+11BCh],0 

Вторая операция обращается к 64-битному регистру, где младшие 32 бита содержат правильный адрес, а старшие 32 бита содержат некоторое количество мусора. Конечно, это приведет к краху.

Решение

Я прочитал, что одним из возможных решений является следующее:

  1. Создайте asm-файл, содержащий следующий код:

    nop 
    nop 
    nop 
    
    mov ecx,r8d 
    cmp dword ptr [rcx+11BCh],0 
    
    nop 
    nop 
    nop 
    
    mov rcx,r8d   // I've replaced ecx with rcx here 
    cmp dword ptr [rcx+11BCh],0 
    
  2. Создайте файл obj, используя этот файл asm и MASM.exe

  3. Откройте файл obj с помощью шестнадцатеричного редактора и найдите 90-е, которые представляют nop
  4. В Flash ocx найдите первую строку байтов между nops и замените ее новой строкой байтов, которая идет после nops. Это изменит его с 32-битных на 64-битные вызовы функций.

Проблема

Я попытался сделать это, создав следующий asm-файл и собрав его с помощью ml64.exe (у меня нет masm.exe, но я думаю, что ml.exe - это новая 32-разрядная версия, и этот код будет только собираться с ml64.exe, возможно из-за только 64-битных операторов?):

TITLE: Print String Assembly Program (test.asm)

.Code
main Proc
nop 
nop 
nop 

mov ecx,r8d 
cmp dword ptr [rcx+11BCh],0 

nop 
nop 
nop 

mov rcx,r8   
cmp dword ptr [rcx+11BCh],0 

main ENDP
END

У меня были проблемы с его сборкой (я продолжал получать ошибки при сопоставлении длины инструкций), пока во втором разделе я не изменил r8d на r8.

Я получил этот объект для сборки, открыл его с помощью шестнадцатеричного редактора и смог найти две строки байтов. Но моя проблема заключается в том, что когда я ищу первую строку байта, которая должна быть во флэш-памяти, я не могу ее найти. Его там нет, поэтому я не могу заменить его вторым.

Что я делаю не так?

Спасибо!

1 Ответ

0 голосов
/ 09 марта 2012
  1. Создайте файл asm, содержащий следующий код:

    nop 
    nop 
    nop 
    
    mov ecx,r8d 
    cmp dword ptr [rcx+11BCh],0 
    
    nop 
    nop 
    nop 
    
    mov rcx,r8d   // I've replaced ecx with rcx here 
    cmp dword ptr [rcx+11BCh],0 
    
  2. Создайте файл obj, используя этот файл asm и MASM.exe

  3. Откройте файл obj с помощью шестнадцатеричного редактора и найдите 90-е, которые представляют nop
  4. В файле ocx во Flash найдите первую строку байтов между nops и замените ее новой строкой байтов, которая приходитпосле nops.Это изменит его с 32-битных на 64-битные вызовы функций.

Я сделал следующий файл asm и собрал его с помощью ml64.exe

TITLE: Print String Assembly Program (test.asm)

.Code
main Proc
nop 
nop 
nop 

mov ecx,r8d 
cmp dword ptr [rcx+11BCh],0 

nop 
nop 
nop 

mov rcx,r8   
cmp dword ptr [rcx+11BCh],0 

main ENDP
END

Я получил этот объект для сборкии открыл его с помощью шестнадцатеричного редактора и смог найти две строки байтов.Я нашел первую строку байта во Flash OCX и изменил ее на вторую.(Единственное фактическое изменение было 41 к 49 в строках)

...