Как поместить байты HASH в адрес памяти с помощью OllyDbg

Я использую OllyDbg для изменения приложения, но я совсем новичок в языке ассемблера, мне нужно поместить хэш MD5 в адрес памяти, адрес памяти назначения хранится в EAX. Как мне это сделать?

введите здесь описание изображения

Хэш, который мне нужно вставить, это dba2d8bf7063faf1275e693661bc9651. Я пробовал следующим образом:

MOV DWORD PTR DS:[EAX],32616264
MOV DWORD PTR DS:[EAX+4],66623864
MOV DWORD PTR DS:[EAX+8],33363037
MOV DWORD PTR DS:[EAX+12],31666166
MOV DWORD PTR DS:[EAX+16],65353732
MOV DWORD PTR DS:[EAX+20],36333936
MOV DWORD PTR DS:[EAX+24],63623136
MOV DWORD PTR DS:[EAX+28],31353639

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

MOV DWORD PTR DS:[EAX], 012B2C60

Где 012B2C60 — хеш-адрес.

Другая проблема, которая возникает у меня, заключается в том, что желтые подчеркнутые байты изменяются при запуске программы (я думаю, это должны быть динамические адреса), поэтому то, что я пишу в этом адресе, изменяется при запуске программы, как я могу предотвратить это?

введите здесь описание изображения


person Manuel23    schedule 02.12.2017    source источник


Ответы (2)


Кстати, зачем вам копировать 32 байта? Хэши MD5 составляют 16 байт. Вы копируете его ASCII-представление?

MOV DWORD PTR DS:[EAX], 012B2C60

Вы не можете скопировать память в память без изменения регистров. Кроме того, последовательность из 8 инструкций dword mov с 32-битным абсолютным адресом не была бы короче, даже если бы ее можно было закодировать, потому что каждой инструкции потребуется адрес 012B2C60.


Если вы можете стереть регистр XMM или YMM (или сохранить/восстановить его в стеке), вы можете скопировать 32 байта, используя 2 пары загрузки/сохранения XMM SSE или один AVX vmovdqu ymm4, [012B2C60] / vmovdqu [eax], ymm4.

Если после этого в программе важна производительность, используйте AVX, если окружающий код уже использует AVX. В противном случае используйте SSE movups с регистром XMM. (Избегайте остановок перехода AVX/SSE или Ложные зависимости Skylake).

Вместо AVX или SSE вы можете реализовать memcpy, загрузив esi, edi и ecx и используя ecx=8 / rep movsd, а затем восстановив регистры. (Для edi вы можете xchg eax, edi перед rep movsd, затем sub edi, 32, затем снова xchg. Однако для производительности IDK, если это лучше, чем push/pop, чтобы сохранить/восстановить его вместе с другими.

Или, если вам не нужно сохранять регистры, rep movsd подходит для размера кода для эффективности однократного запуска.

Если ваш код для этого запускается только один раз при запуске программы, то, если размер кода не является реальной проблемой, вероятно, проще всего использовать немедленные данные вместо копирования. Это не очень хорошо для общей эффективности использования пространства, потому что каждое двойное слово данных требует 3 дополнительных байта: код операции, modrm и disp8 (за исключением первого, который использует голый режим адресации [eax]. push имеет лучшую плотность для немедленных данных, но может только передавать в стек.

64-битный режим помогает лишь незначительно; mov r64, imm64 составляет 10 байт, но работает только с назначением регистра.

person Peter Cordes    schedule 03.12.2017
comment
Спасибо, да, это представление ASCII, я решил переместить байты с помощью реестра XMM, таким образом, я могу переместить 32 байта всего двумя командами. Но у меня осталась проблема адресов, о которых я упоминаю в первой публикации... - person Manuel23; 05.12.2017
comment
@Manuel23: 4 инструкции: 2 загрузить / 2 сохранить. (И слово, которое вам нужно, это регистры, а не registry). - person Peter Cordes; 05.12.2017
comment
@ Manuel23: Я не понимаю, какая у тебя проблема с адресами. movdqu xmm0, [012B2C60] или [012B2C60+16] для загрузки, и у вас уже есть адрес в eax, поэтому вы можете хранить с режимами адресации [eax] и [eax+16]. - person Peter Cordes; 05.12.2017
comment
@Manuel23: О, последний абзац. Это похоже на перемещение / исправление исполняемого файла, загружаемого по адресу, отличному от ожидаемого. Вы заменяете какой-то существующий код, у которого был адрес в этом месте? - person Peter Cordes; 05.12.2017
comment
Да, если вы посмотрите на первое изображение, я установил NOP на полную функцию, но осталось 8 байтов с желтым подчеркиванием, эти байты изменяются при перезапуске приложения, что разрушает мои модификации. - person Manuel23; 05.12.2017
comment
@ Manuel23: Вы должны были сказать это в тексте, а также опубликовать уменьшенное изображение. Я прочитал текст и не увидел ничего неясного, что заставило бы меня подумать, что мне нужно сослаться на изображение. В любом случае, да, если вы NOPировали некоторый код, который ранее включал адрес, загрузчик программ Windows все равно добавит смещение перемещения к этим байтам. Если ваш код имеет фиксированный адрес загрузки, вы можете учесть это и использовать такие данные, как x - y + 0x90909090 или что-то в этом роде, чтобы конечным результатом перемещения было 4 NOP. Или используйте длинный NOP, чтобы эти 4 байта были частью неиспользуемого disp32 в 0F F0 NOP. - person Peter Cordes; 05.12.2017
comment
Да, извините, я говорю по-испански, и мне очень трудно объяснить это по-английски. Можно ли удалить смещение перемещения этих байтов? Я хотел бы использовать эти байты для написания новых команд... - person Manuel23; 05.12.2017
comment
@ Manuel23: IDK, как легко отредактировать таблицу символов / перемещений в заголовках PE, чтобы удалить это перемещение. Это DLL или вы можете просто отключить ASLR, если это исполняемый файл, чтобы он каждый раз загружался по одному и тому же адресу? Если код, зависящий от позиции, подходит, вы можете обойти перемещение, используя 0x90909090 - relocation, где relocation — это сумма, которая добавляется при загрузке программы. Таким образом, на диске байты будут неправильными, но при загрузке исправление сделает их такими, какими вы хотите их видеть. Это не обязательно должны быть NOP; может быть что угодно. - person Peter Cordes; 05.12.2017
comment
@ Manuel23: Однако редактирование заголовка PE было бы намного чище, поэтому попробуйте сделать это. (Понятия не имею, как, я не занимаюсь редактированием Windows или двоичных файлов, я просто знаю, как работает динамическая компоновка и ASLR.) - person Peter Cordes; 05.12.2017

  • сохраните свой хэш-код в нижней части сегмента кода. обычно вы можете увидеть много свободных байтов в сегменте кода, который никогда не меняется. они равны нулю. сегмент данных предназначен для ваших глобальных переменных, поэтому они могут меняться, но байты сегмента кода никогда не меняются.
  • используйте функцию memcpy, чтобы скопировать эти байты в целевой адрес памяти.
person Amir    schedule 14.12.2017