Сейчас на форуме: cppasm, asfa (+6 невидимых)

 eXeL@B —› Вопросы новичков —› Как при цепочечном копировании секции, байты могут измениться дважды?
Посл.ответ Сообщение

Ранг: 30.1 (посетитель)
Активность: 0.070
Статус: Участник

Создано: 04 июля 2016 02:06
· Личное сообщение · #1

Работаю в Олли-дебагере.
У меня есть такой код, который побайтно копирует из секции 0x07340000 в секцию 0x00401000 код, размером 0x01456000 байт.
Code:
  1. 046C5F25    89D7                     MOV EDI,EDX                                   ; edx=00401000
  2. 046C5F27    89CE                     MOV ESI,ECX                                   ; ecx=07340000
  3. 046C5F29    89C1                     MOV ECX,EAX                                   ; eax=01456000,(Pered Copy section)
  4. 046C5F2B    F3:A4                    REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
  5. 046C5F2D    C685 5C1C2B1C 56         MOV BYTE PTR SS:[EBP+0x1B1C2D4B],0x34  ; (Posle Copy section)

Ставлю железный брейкпоинт на запись дворда по адресу 0x00492540 (База+смещение = 0x00400000+0x00092540). Когда выполнение останавливается на записи в этот адрес, то при помощи F7 прослеживаю записываемые байты. Они такие-же как по такому-же смещению в исходной секции. (Ну тут все верно, цепочечная операция скопировала байты). Далее ставлю железный брейкпоинт на исполнение кода, на адрес 0х046C5F2D (следующий за цепочечной операцией адрес) . Жму кнопку Play (F9).
Выполнение останавливается после копирования, но тот дворд почему-то изменился. Причем брейкпоинт на повторную запись не сработал.
Экспериментальным путем выяснил:
1) Копируемая секция вначале, на одну десятую часть забита значащими байтами, остальное нулевые байты.
2) Повторное изменение контроллируемого дворда происходит после копирования примерно половины всей секции. Точное количество скопированных байт, перед повторным изменением дворда, вычислить не получается, оно всегда разное (скорее всего зависит от времени копирования нулевых байт).
Вопрос в том, как отловить эту повторную перезапись, моего дворда? То-есть как в отладчике попасть в этот код, который перезаписывает мой дворд? Если я даже примерно не знаю где он находится.




Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 04 июля 2016 02:58 · Поправил: -=AkaBOSS=-
· Личное сообщение · #2

Kuzya69 пишет:
но тот дворд почему-то изменился. Причем брейкпоинт на повторную запись не сработал.

изменился на что конкретно? на то что копировал, или на что? а окружающие его данные изменились?
и вообще - проблема состоит в том что бряк не работает, или в том, что дворд откуда-то меняется и неясно кто это сделал?

на каком этапе загрузки модуля выполняется упомянутое копирование?


Kuzya69 пишет:
Точное количество скопированных байт, перед повторным изменением дворда, вычислить не получается, оно всегда разное

без тестового модуля сложно вкурить тему, но вероятней всего это процессорная оптимизация блочной операции.
проц посмотрел на побайтовое копирование такого блока как на говно, посмотрел на счётчик байт, и малость ускорил дело чтоб гору чайной ложкой не черпать.

у интела сказано так:
P6 family processors are unable to report data breakpoints exactly for the REP MOVS
and REP STOS instructions until the completion of the iteration after the iteration in
which the breakpoint occurred.


говоря по-русски - пока блок не докопирует, брейкпоинты идут лесом


Kuzya69 пишет:
Жму кнопку Play (F9).

..и раздаётся музыка



Ранг: 30.1 (посетитель)
Активность: 0.070
Статус: Участник

Создано: 04 июля 2016 12:53 · Поправил: Kuzya69
· Личное сообщение · #3

-=AkaBOSS=- пишет:
изменился на что конкретно?на то что копировал, или на что?

Программа ломанная, поэтому это второе изменение дворда, происходит только в ломанной программе. В оригинальной проге один jmp, а в ломанной другой. Первое изменение дворда в jmp-е, происходит за счет цепочечной операции, как это и задумано в оригинале, а вот второе изменение делается каким-то непонятным мне способом. Как-бы на это можно и забить. Я уже понял как другой хакер сломал программу. Но любопытство не дает покоя. Как он умудрился прервать цепочечную команду, изменить дворд, и потом опять запустить цепочечную команду?
-=AkaBOSS=- пишет:
а окружающие его данные изменились?

Нет. изменились только 4 байта в одном jmp-е.
-=AkaBOSS=- пишет:
и вообще - проблема состоит в том что бряк не работает, или в том, что дворд откуда-то меняется и неясно кто это сделал?

Ну, что бряк не сработал, как-бы важно, но во вторую очередь. А вот как отловить код, который делает эту вторую подмену?
-=AkaBOSS=- пишет:
на каком этапе загрузки модуля выполняется упомянутое копирование?

Я не очень сильный реверсер, но на сколько я понимаю это последний этап распаковки, перед выходом на OEP.
-=AkaBOSS=- пишет:
говоря по-русски - пока блок не докопирует, брейкпоинты идут лесом

Так ведь первое изменение ловится на брейкпоинт, не ловится только второе.
-=AkaBOSS=- пишет:
Жму кнопку Play (F9).
..и раздаётся музыка

Ну если она на обозначение кнопки Play в бытовой аппаратуре похожа. Так проще объяснить, что делаю.




Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 04 июля 2016 14:16
· Личное сообщение · #4

Kuzya69 пишет:
А вот как отловить код, который делает эту вторую подмену?

как вариант - поставь запрет на запись на всю страницу и жди где упадёт.

Кстати, насколько я знаю, WriteProcessMemory пишет память через ядрёные функции напрямую, и отловить её из перезаписываемого процесса хрен получится. Мож так оно и сделано?

и еще - Kuzya69 пишет:
Ставлю железный брейкпоинт на запись дворда

железные бряки зависят от отладочных регистров, которые хранятся в контексте, а контекст у каждого треда свой. Запись может из другого треда вестись, попробуй memory breakpoint ставить.



Ранг: 30.1 (посетитель)
Активность: 0.070
Статус: Участник

Создано: 04 июля 2016 14:56 · Поправил: Kuzya69
· Личное сообщение · #5

-=AkaBOSS=- пишет:
как вариант - поставь запрет на запись на всю страницу и жди где упадёт.

Дык упадет сразу-же, ведь цепочечная операция сама пишет в эту страницу.
-=AkaBOSS=- пишет:
...попробуй memory breakpoint ставить.

Ставил и memory breakpoint, то-же самое, не ловится.
-=AkaBOSS=- пишет:
WriteProcessMemory пишет память через ядрёные функции напрямую, и отловить её из перезаписываемого процесса хрен получится

Жаль, а так хотелось код посмотреть, чтоб понять как там адрес фикса определяется.

Кстати, только-что трейс этой цепочечной операции закончился, второй перезаписи дворда не произошло. Оно произошло где-то позже, после того как запустил прогу на дальнейшее исполнение. Может это быть реализовано с помощью Wait-функций? Может код ждет какого-то события, типа бездействия, или долгой работы не в 3-м кольце, и сразу включается обработчик события?




Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 04 июля 2016 19:47 · Поправил: -=AkaBOSS=-
· Личное сообщение · #6

Kuzya69 пишет:
Дык упадет сразу-же, ведь цепочечная операция сама пишет в эту страницу.

ну дык теста ради - не пиши ничего туда. пока просто лови обращения к адресу. коль прога уже ломаная, то оно и так перезапишется.

Kuzya69 пишет:
второй перезаписи дворда не произошло. Оно произошло где-то позже

Kuzya69 пишет:
на сколько я понимаю это последний этап распаковки, перед выходом на OEP

а модули какие-нибудь грузятся в это время? мож прога импорт настраивала, а в какой-то её длл инжект патча висит? в принципе, удобный вариант, так как заранее можно знать состояние проги в момент загрузки длл.

вообще, если всё так сложно и неясно - сделай свой инжект кода перед этим злоедучим двордом, и выполни нужный тебе код в другом месте.

ну или как я уже подсказывал - попробуй софт бряки на выполнение WriteProcessMemory/NtWriteVirtualMemory, авось сработает

Kuzya69 пишет:
понять как там адрес фикса определяется

чи ни высшая математика - hModule+rva. попробуй кстати тупой вариант - поищи адрес/рва своего дворда через CheatEngine/Artmoney. авось и выловишь чего умное.


 eXeL@B —› Вопросы новичков —› Как при цепочечном копировании секции, байты могут измениться дважды?
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати