Сейчас на форуме: tyns777 (+5 невидимых)

 eXeL@B —› Программирование —› Программное нахождение IAT
Посл.ответ Сообщение


Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 24 сентября 2007 14:19
· Личное сообщение · #1

Я тут задолбался уже с этим вопросом.Дело казалось бы тривиальное,но,когда PE-файл обработан протектором(переходники и всё остальное),всё оказывается как-то не просто.
Собственно вот мой код,который пытается определить границы IAT.В функцию подаётся примерный OEP,а именно обратный адрес после перехвата вызова GetModuleHandleA,которая вызывается одной из первых после OEP.

; ########################################### ProcessIAT #########################################
ProcessIAT proc USES ebx edx esi dwApproxOEP:DWORD

local fResult:BOOL

local dwTempProtect:DWORD

local pBaseOfData:PVOID

local dwInitialIATAddress:DWORD

local pIATStart:PVOID
local pIATEnd:PVOID
local dwIATSize:DWORD

and fResult, 0

push NULL
call GetModuleHandleA

mov ebx, eax
add ebx, dword ptr [ebx + IMAGE_DOS_HEADER.e_lfanew]
mov ebx, dword ptr [ebx + IMAGE_NT_HEADERS.OptionalHeader.BaseOfData]
add ebx, eax
mov pBaseOfData, ebx ; <-- Дело в том,что часто это поле заголовка указывает именно на IAT

; /*
; * Поиск границ IAT
; */

; /* Нахождение адреса IAT, через который вызывалась функция GetModuleHandleA */
mov eax, dwApproxOEP

@@seek_call_method:
dec eax

cmp word ptr [eax], 15FFh
jz @@call_method_found

cmp word ptr [eax], 25FFh
jz @@call_method_found

cmp word ptr [eax], 1D8Bh
jz @@call_method_found

cmp word ptr [eax], 358Bh
jz @@call_method_found

cmp word ptr [eax], 3D8Bh
jz @@call_method_found

cmp word ptr [eax], 2D8Bh
jz @@call_method_found

jmp @@seek_call_method

@@call_method_found:

; /* В EDX кладём VA, по которому располагается одна из ячеек IAT */
mov edx, dword ptr [eax+02]
mov dwInitialIATAddress, edx

; /* Пытаемся определить начало IAT */

@@define_IAT_start:

cmp edx, pBaseOfData
jz @@IAT_start_reached

sub edx, sizeof DWORD

cmp dword ptr [edx], 0
jnz @@define_IAT_start

sub edx, sizeof DWORD

cmp dword ptr [edx], 0
jz @@IAT_start_reached

; /* Для проверки содержимого ячейки IAT ищем место в секции кода, где происходит обращение к этой ячейке */
push g_dwCodeEnd
push g_dwCodeStart
push edx
call SeekIATReference
test eax, eax
jnz @@define_IAT_start

@@IAT_start_reached:
; Тут я уже не знаю,как проверять,сколько нужно добавить к EDX
mov pIATStart, edx

; /* Пытаемся определить конец IAT */

mov edx, dwInitialIATAddress

@@define_IAT_end:

add edx, sizeof DWORD

cmp dword ptr [edx], 0
jnz @@define_IAT_end

add edx, sizeof DWORD

cmp dword ptr [edx], 0
jz @@IAT_end_reached

; /* Для проверки содержимого ячейки IAT ищем место в секции кода, где происходит обращение к этой ячейке */
push g_dwCodeEnd
push g_dwCodeStart
push edx
call SeekIATReference
test eax, eax
jnz @@define_IAT_end

@@IAT_end_reached:
mov pIATEnd, edx
sub edx, pIATStart

mov dwIATSize, edx

...
ProcessIAT endp

; ####################################### SeekIATReference #######################################
SeekIATReference proc USES ebx edx dwIATVA:DWORD, dwCodeStart:DWORD, dwCodeEnd:DWORD

local fResult:BOOL

and fResult, 0

mov edx, dwIATVA
mov eax, dwCodeStart

@@seek_ref:
cmp word ptr [eax], 15FFh
jz @@ref_found

cmp word ptr [eax], 25FFh
jz @@ref_found

cmp word ptr [eax], 1D8Bh
jz @@ref_found

cmp word ptr [eax], 358Bh
jz @@ref_found

cmp word ptr [eax], 3D8Bh
jz @@ref_found

cmp word ptr [eax], 2D8Bh
jz @@ref_found

@@seeking_loop:
inc eax
cmp eax, dwCodeEnd
jl @@seek_ref

; /* Последняя попытка найти обращение к возможному адресу IAT в коде программы */

; ::::::::::::::::::::::::::::::::::::::::::::::::::::
mov eax, dwCodeStart

@@seek_ref_aux:
cmp dword ptr [eax], edx
jnz @@seeking_loop_aux

or fResult, 01

jmp @@ret

@@seeking_loop_aux:
inc eax
cmp eax, dwCodeEnd
jl @@seek_ref_aux

jmp @@ret

; ::::::::::::::::::::::::::::::::::::::::::::::::::::

@@ref_found:
mov ebx, dword ptr [eax+02]

cmp ebx, edx
jnz @@seeking_loop

or fResult, 01

@@ret:
mov eax, fResult
ret

SeekIATReference endp


В общем,я совсем запустался с этим.Как ImpRec определяет границы IAT,когда нажимаешь кнопку "IAT Autosearch"??Ведь если ему дать правильный OEP,то в сишной программе он наверняка определит правильные границы.
Если проверять каждый адрес,находящийся в предполагаемой IAT,то моя функция SeeIATReference бывает не находит в секции кода обращения к какому-нибудь адресу IAT,хотя это должен быть 100% импорт.В итоге снова границы определяются неправильно.

Было бы здорово,если бы кто-то предложил какие-то конструктивные идеи по этому поводу.

-----
the Power of Reversing team




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 24 сентября 2007 15:01
· Личное сообщение · #2

нет необходимости сохранять edx

часть исходников ImpRec'а открыта




Ранг: 271.6 (наставник), 2thx
Активность: 0.30
Статус: Участник

Создано: 24 сентября 2007 15:16
· Личное сообщение · #3

А ссылку можно?
Никогда не видел.

-----
iNTERNATiONAL CoDE CReW




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 24 сентября 2007 15:28 · Поправил: __
· Личное сообщение · #4

Spirit
должно быть в архиве
wasm.ru/baixado.php?mode=tool&id=64




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 24 сентября 2007 15:42
· Личное сообщение · #5

Весьма конструктивные ответы...

Тут подумал,что можно было бы сделать следующим образом.
Определяем адрес в IAT с помощью примерной OEP,как я описал выше.Далее проверяем каждую ячейку кроме нулевых в такой последовательности:

1. Сначала с помощью функции,которая определяет,лежит ли адрес предполагаемого импорта в диапазоне загруженных библиотек.Функция такая:

; #################################### SearchForTrueModuleReference ##############################
SearchForTrueModuleReference proc USES ebx ecx edx esi dwReference:DWORD

local fResult:BOOL

local adwModHandles[1024]:HANDLE
local cbNeeded:DWORD

local ModInfo:MODULEINFO

and fResult, 0

mov ebx, dwReference

lea esi, adwModHandles

lea eax, cbNeeded
push eax
push sizeof adwModHandles
push esi
push INVALID_HANDLE_VALUE
call EnumProcessModules
test eax, eax
jz @@ret

mov ecx, cbNeeded
shr ecx, 2

@@:
dec ecx
jz @@ret

; /* Мы не будем проверять первый элемент массива(ECX == 0), т.к. это и есть сам исполняемый модуль */

push ecx ; Сохраняем регистр ECX, потому что GetModuleInformation наглым образом изменяет этот регистр

push sizeof MODULEINFO
lea eax, ModInfo
push eax
push dword ptr [esi + ecx * sizeof DWORD]
push INVALID_HANDLE_VALUE
call GetModuleInformation
test eax, eax
jz @@ret

pop ecx ; Восстанавливаем регистр ECX

mov eax, [esi + ecx * sizeof DWORD]
add eax, dword ptr ModInfo.dwSizeOfImage

cmp ebx, [esi + ecx * sizeof DWORD]
jl @b

cmp ebx, eax
ja @b

or fResult, 01

jmp @@ret

@@ret:
mov eax, fResult
ret

SearchForTrueModuleReference endp


2. Если не лежит,то проверяем права доступа к адресу с помощью функции IsBadCodePtr.По идее переходник протектора(если это он) должен иметь read access.Таким образом мы попытаемся исключить мусорные адреса.На MSDN правда пишут,что функции IsBadXxxPtr -- это бомба замедленного действия,но я думаю,что SEH должен решить эту проблему.

3. Если права доступа позволяют,то проверяем не адрес ли это в пределах исследуемого исполняемого модуля, т.е. ImageBase + SizeOfImage.Если это он,то значит это не адрес импорта.

-----
the Power of Reversing team




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 24 сентября 2007 15:49
· Личное сообщение · #6

DillerInc пишет:
Сохраняем регистр ECX, потому что GetModuleInformation наглым образом изменяет этот регистр


чего наглым то? она вовсе не обязана его сохранять ;)



Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 24 сентября 2007 15:58
· Личное сообщение · #7

DillerInc пишет:
Весьма конструктивные ответы...


код плохо читается без форматирования, выглядит так будто откуда-то вырипан, почему не использовать invoke, неговоря о том что лучше переписать на С ?




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 24 сентября 2007 16:05
· Личное сообщение · #8

[offtop]
__
Может закончим флуд??Если сказать по делу нечего,то лучше просто промолчать.
[/offtop]

-----
the Power of Reversing team




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 24 сентября 2007 16:10
· Личное сообщение · #9

DillerInc
хорошо буду молчать как партизан

неплохо было бы начинать топик с объяснения для чего это нужно, под какой протектор или это
плагин к ImpRec'у или попытка написать свой ImpRec

все, далее не пишу в этом топе, отдыхайте =)




Ранг: 240.5 (наставник)
Активность: 0.190
Статус: Участник
Author of ACKiller

Создано: 24 сентября 2007 16:12
· Личное сообщение · #10

DillerInc
1) Не очень понял, что означает /* Последняя попытка найти обращение к возможному адресу IAT в коде программы */ ?

2) Откуда берутся g_dwCodeEnd и g_dwCodeStart? Если значения BaseOfCode и SizeOfCode из NT_HEADERS, то вообще-то они не надёжны...

3) Твой вариант поиска конца ИАТ можно легко обмануть, подсунув между модулями вместо нулей мусор. Поэтому нужно, например, считать за разделитель Н-ное кол-во мусора (в т.ч. нулей), и если после них ничего дельного нету, то тогда это конец. То же и с началом.

4) Лучше наверное сделать проверку на принадлежность функции данного модуля более жесткой - считать валидным адрес не просто из границ модуля, а еще и находящегося в таблице экспорта этого модуля.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 24 сентября 2007 19:23
· Личное сообщение · #11

А такое дело: надо найти именно саму ИАТ с границами? Потому что у меня в QuickUnpack при востановлении импорта ищутся переходники, похожие на импорт, и уже разбираются по отдельности. Имхо, для хитрожопых протов это понадёжней будет.




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 24 сентября 2007 20:18
· Личное сообщение · #12

__ пишет:
неплохо было бы начинать топик с объяснения для чего это нужно, под какой протектор или это
плагин к ImpRec'у или попытка написать свой ImpRec

...моё приложение(внедрённая библиотека) пытается восстановить импорт в приложении,защищённом StarForce.В принципе переходники,если их так можно назвать в данном случае,восстановлены.Требуется заодно и поправить оригинальную IAT.Проблема в правильном определении её границ.

HoBleen пишет:
1) Не очень понял, что означает /* Последняя попытка найти обращение к возможному адресу IAT в коде программы */ ?

...это когда не удаётся найти вызов импорта с помощью поиска опкодов команд: call [ref], jmp [ref], вызовы через регистры, то тогда я ищу просто VA IAT в коде как сигнатуру.

HoBleen пишет:
2) Откуда берутся g_dwCodeEnd и g_dwCodeStart? Если значения BaseOfCode и SizeOfCode из NT_HEADERS, то вообще-то они не надёжны...

...именно они.Но как тогда более надёжно определить границы кода??По имени секции ведь не станешь искать...

HoBleen пишет:
3) Твой вариант поиска конца ИАТ можно легко обмануть, подсунув между модулями вместо нулей мусор.

...ну,пока такого изврата я даже у StarForce не видел.

Archer пишет:
надо найти именно саму ИАТ с границами?

...да.Я думаю,лучше сначала найти,где искать.А потом уже обрабатывать,что нашёл.

В общем,я тут ещё попробую реализовать ту задумку,где используется функция SeekForTrueModuleReference и далее.Может будет толк.Позже отпишусь.

-----
the Power of Reversing team




Ранг: 62.3 (постоянный)
Активность: 0.020
Статус: Участник

Создано: 25 сентября 2007 06:20
· Личное сообщение · #13

DillerInc пишет:
HoBleen пишет:
3) Твой вариант поиска конца ИАТ можно легко обмануть, подсунув между модулями вместо нулей мусор.
...ну,пока такого изврата я даже у StarForce не видел.


В следующей версии обязательно увидишь ну а если без приколов, то тот же стар может в ИАТ врезать свой вызов вм , и не гаронтированно что там не будет 8 нулей, и еще один вариант стар может сделать так чтоб начало ИАТ лежит в одной секции а ее хвост в другой, я не помню как именно тогда заканчивается ИАТ, но импереку длину ИАТ приходится вбивать ручками и в дампе править секции. (стар частенько так крутит секциями рандомайзом, так что учти)




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 25 сентября 2007 21:27
· Личное сообщение · #14

Faza
Блин,таких приколов не хотелось бы...
Я смотрел UnpackMe с tuts4you, защищённое актуальным протектором.Так там первая секция называлась .TEXT, и в ней лежала IAT.Далее за ней шла sforce3.
Обе секции попадали под диапазон BaseOfCode+SizeofCode.
Но там мусора не было между модулями.

Я тут меж тем написал код,который у меня успешно отработал в двух случаях.Второй случай был замечателен тем,что IAT находилась в той же секции,что и код(sforce3), и между кодом и началом IAT не было ни одного нулевого байтика.Единственное,что указывало,что по такому-то адресу начинаются данные,было поле BaseOfData.

Код следующий:


; ########################################### ProcessIAT #########################################
ProcessIAT proc USES ebx ecx edx esi dwApproxOEP:DWORD

local fResult:BOOL

local dwTempProtect:DWORD

local pImageBase:PVOID
local pImageEdge:PVOID

local dwInitialIATAddress:DWORD

local pIATStart:PVOID
local pIATEnd:PVOID
local dwIATSize:DWORD

and fResult, 0

; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
; /* Устанавливаем SEH, перекрывающий всю функцию */
assume fs:nothing

push offset ExceptionHandlerOuter
push fs:[0]
mov fs:[0], esp

assume fs:error

mov g_seh_Outer.SafeEip, offset SafePlace_Outer
mov g_seh_Outer.PrevEsp, esp
mov g_seh_Outer.PrevEbp, ebp
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::

push NULL
call GetModuleHandleA
mov pImageBase, eax

mov ebx, eax
add ebx, dword ptr [ebx + IMAGE_DOS_HEADER.e_lfanew]
mov ebx, dword ptr [ebx + IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage]
add ebx, eax
mov pImageEdge, ebx

; /*
; * Поиск границ IAT
; */

; /* Нахождение адреса IAT, через который вызывалась функция GetModuleHandleA */
mov eax, dwApproxOEP

@@seek_call_method:
dec eax

cmp word ptr [eax], 15FFh
jz @@call_method_found

cmp word ptr [eax], 25FFh
jz @@call_method_found

cmp word ptr [eax], 1D8Bh
jz @@call_method_found

cmp word ptr [eax], 358Bh
jz @@call_method_found

cmp word ptr [eax], 3D8Bh
jz @@call_method_found

cmp word ptr [eax], 2D8Bh
jz @@call_method_found

jmp @@seek_call_method

@@call_method_found:

; /* В EDX кладём адрес VA, по которому располагается одна из ячеек IAT */
mov edx, dword ptr [eax+02]
mov dwInitialIATAddress, edx

; /* Пытаемся определить начало IAT */

@@define_IAT_start:

; /* ECX используется как счётчик нулевых DWORD'ов */
xor ecx, ecx

@@loop_towards_start:
cmp ecx, 02
jz @@IAT_start_reached

sub edx, sizeof DWORD

inc ecx

cmp dword ptr [edx], 0
jz @@loop_towards_start

; /*
; * Первый этап проверки */
; */
mov eax, dword ptr [edx]

; /* Принадлежит ли адрес, одной из загруженных библиотек?? */
push eax
call SearchForTrueModuleReference
test eax, eax
jnz @@define_IAT_start

; /*
; * Второй этап проверки */
; */
mov eax, dword ptr [edx]

add eax, pImageBase

; /* Лежит ли адрес в пределах исследуемого модуля?? */
cmp eax, pImageBase
jl @f

cmp eax, pImageEdge
ja @f

; /* Если да, то это скорее всего какой-нибудь RVA, указывающий на название библиотеки, функции и т.д. */
jmp @@IAT_start_reached

; /*
; * Третий этап проверки */
; */

@@:
mov eax, dword ptr [edx]

; /* Имеем ли мы права на чтение по текущему адресу */
and g_fIsBadPointer, 0

; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
; /* Устанавливаем SEH, который защищает команду MOV */
assume fs:nothing

push offset ExceptionHandlerInner
push fs:[0]
mov fs:[0], esp

assume fs:error

mov g_seh_Inner.SafeEip, offset SafePlace_Inner_Start
mov g_seh_Inner.PrevEsp, esp
mov g_seh_Inner.PrevEbp, ebp
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::

mov eax, dword ptr [eax]

; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
; /* Место, с которого должно безопасно продолжиться выполнение после возможной ошибки */
SafePlace_Inner_Start:

assume fs:nothing

pop fs:[0]
add esp, sizeof DWORD

assume fs:error
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::

; /* Если мы имеем права на чтение, то это скорее всего переходник протектора */
cmp g_fIsBadPointer, 01
jnz @@define_IAT_start

@@IAT_start_reached:
; /* Добавляем необходимое кол-во байт к EDX, чтобы установить его точно в начало IAT */
shl ecx, 2
add edx, ecx

mov pIATStart, edx

; /* Пытаемся определить конец IAT */

mov edx, dwInitialIATAddress

@@define_IAT_end:

; /* ECX используется как счётчик нулевых DWORD'ов */
xor ecx, ecx

@@loop_towards_end:
cmp ecx, 02
jz @@IAT_end_reached

add edx, sizeof DWORD

inc ecx

cmp dword ptr [edx], 0
jz @@loop_towards_end

; /*
; * Первый этап проверки */
; */
mov eax, dword ptr [edx]

; /* Принадлежит ли адрес, одной из загруженных библиотек?? */
push eax
call SearchForTrueModuleReference
test eax, eax
jnz @@define_IAT_end

; /*
; * Второй этап проверки */
; */
mov eax, dword ptr [edx]

add eax, pImageBase

; /* Лежит ли адрес в пределах исследуемого модуля?? */
cmp eax, pImageBase
jl @f

cmp eax, pImageEdge
ja @f

; /* Если да, то это скорее всего какой-нибудь RVA, указывающий на название библиотеки, функции и т.д. */
jmp @@IAT_end_reached

; /*
; * Третий этап проверки */
; */

@@:
mov eax, dword ptr [edx]

; /* Имеем ли мы права на чтение по текущему адресу */
and g_fIsBadPointer, 0

; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
; /* Устанавливаем SEH, который защищает команду MOV */
assume fs:nothing

push offset ExceptionHandlerInner
push fs:[0]
mov fs:[0], esp

assume fs:error

mov g_seh_Inner.SafeEip, offset SafePlace_Inner_End
mov g_seh_Inner.PrevEsp, esp
mov g_seh_Inner.PrevEbp, ebp
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::

mov eax, dword ptr [eax]

; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
; /* Место, с которого должно безопасно продолжиться выполнение после возможной ошибки */
SafePlace_Inner_End:

assume fs:nothing

pop fs:[0]
add esp, sizeof DWORD

assume fs:error
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::

cmp g_fIsBadPointer, 01
jnz @@define_IAT_end

@@IAT_end_reached:
mov pIATEnd, edx
sub edx, pIATStart

mov dwIATSize, edx

or fResult, 01

; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::
; /* Место, с которого должно безопасно продолжиться выполнение после возможной ошибки */
SafePlace_Outer:

assume fs:nothing

pop fs:[0]
add esp, sizeof DWORD

assume fs:error
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::

@@ret:
mov eax, fResult
ret

ProcessIAT endp


-----
the Power of Reversing team





Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 25 сентября 2007 21:33 · Поправил: DillerInc
· Личное сообщение · #15

Во,надо добавить следующее:


SEH STRUCT
SafeEip dd ? ; Точка, откуда будет продолжено выполнение программы
PrevEsp dd ? ; Предыдущее значение ESP
PrevEbp dd ? ; Предыдущее значение EBP
SEH ENDS

.data?

g_seh_Inner SEH <>
g_seh_Outer SEH <>

.code

; #################################### ExceptionHandlerInner #####################################
ExceptionHandlerInner proc C USES esi pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD

; /* Правим контекст, в котором произошло исключение */
push dword ptr g_seh_Inner.SafeEip
push dword ptr g_seh_Inner.PrevEsp
push dword ptr g_seh_Inner.PrevEbp

mov eax, pContext

pop dword ptr [eax+CONTEXT.regEbp]
pop dword ptr [eax+CONTEXT.regEsp]
pop dword ptr [eax+CONTEXT.regEip]

; /* Устанавливаем флаг, сигнализирующий, что произошло исключение из-за ошибки доступа */
or g_fIsBadPointer, 01

; /* Возвращаем значение ExceptionContinueExecution (0) */
xor eax, eax
ret

ExceptionHandlerInner endp

; #################################### ExceptionHandlerOuter #####################################
ExceptionHandlerOuter proc C USES esi pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD

; /* Правим контекст, в котором произошло исключение */
push dword ptr g_seh_Outer.SafeEip
push dword ptr g_seh_Outer.PrevEsp
push dword ptr g_seh_Outer.PrevEbp

mov eax, pContext

pop dword ptr [eax+CONTEXT.regEbp]
pop dword ptr [eax+CONTEXT.regEsp]
pop dword ptr [eax+CONTEXT.regEip]

; /* Возвращаем значение ExceptionContinueExecution (0) */
xor eax, eax
ret

ExceptionHandlerOuter endp


-----
the Power of Reversing team




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 25 сентября 2007 23:14
· Личное сообщение · #16

не могу пройти мимо %)

функция SE Handler должна быть cdecl




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 26 сентября 2007 08:56
· Личное сообщение · #17

__ пишет:
функция SE Handler должна быть cdecl

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

-----
the Power of Reversing team




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 26 сентября 2007 12:34
· Личное сообщение · #18

в win9x не будет работать, в 2k/XP есть защита "от дурака" поэтому работает




Ранг: 303.7 (мудрец), 4thx
Активность: 0.190
Статус: Участник
tPORt Manager

Создано: 26 сентября 2007 17:47
· Личное сообщение · #19

DillerInc
Диллер, ты псих. У старовцев есть чел, который шутшит все форумы реверсерские и докладывает разработчикам если что, если что, то защищает стар, лучше иди в приват.


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


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