Посл.ответ |
Сообщение |
Ранг: 283.6 (наставник), 56thx Активность: 0.13↘0 Статус: Участник 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.07↘0 Статус: Участник
|
Создано: 24 сентября 2007 15:01 · Личное сообщение · #2
нет необходимости сохранять edx
часть исходников ImpRec'а открыта
| Сообщение посчитали полезным: |
Ранг: 271.6 (наставник), 2thx Активность: 0.3↘0 Статус: Участник
|
Создано: 24 сентября 2007 15:16 · Личное сообщение · #3
А ссылку можно?
Никогда не видел.
----- iNTERNATiONAL CoDE CReW | Сообщение посчитали полезным: |
Ранг: 115.1 (ветеран), 3thx Активность: 0.07↘0 Статус: Участник
|
Создано: 24 сентября 2007 15:28 · Поправил: __ · Личное сообщение · #4
Spirit
должно быть в архиве
wasm.ru/baixado.php?mode=tool&id=64
| Сообщение посчитали полезным: |
Ранг: 283.6 (наставник), 56thx Активность: 0.13↘0 Статус: Участник 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.07↘0 Статус: Участник
|
Создано: 24 сентября 2007 15:49 · Личное сообщение · #6
DillerInc пишет:
Сохраняем регистр ECX, потому что GetModuleInformation наглым образом изменяет этот регистр
чего наглым то? она вовсе не обязана его сохранять ;)
| Сообщение посчитали полезным: |
Ранг: 115.1 (ветеран), 3thx Активность: 0.07↘0 Статус: Участник
|
Создано: 24 сентября 2007 15:58 · Личное сообщение · #7
DillerInc пишет:
Весьма конструктивные ответы...
код плохо читается без форматирования, выглядит так будто откуда-то вырипан, почему не использовать invoke, неговоря о том что лучше переписать на С ?
| Сообщение посчитали полезным: |
Ранг: 283.6 (наставник), 56thx Активность: 0.13↘0 Статус: Участник Author of GeTaOEP
|
Создано: 24 сентября 2007 16:05 · Личное сообщение · #8
[offtop]
__
Может закончим флуд??Если сказать по делу нечего,то лучше просто промолчать.
[/offtop]
----- the Power of Reversing team | Сообщение посчитали полезным: |
Ранг: 115.1 (ветеран), 3thx Активность: 0.07↘0 Статус: Участник
|
Создано: 24 сентября 2007 16:10 · Личное сообщение · #9
DillerInc
хорошо буду молчать как партизан
неплохо было бы начинать топик с объяснения для чего это нужно, под какой протектор или это
плагин к ImpRec'у или попытка написать свой ImpRec
все, далее не пишу в этом топе, отдыхайте =)
| Сообщение посчитали полезным: |
Ранг: 240.5 (наставник) Активность: 0.19↘0 Статус: Участник 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.34↘0.25 Статус: Модератор retired
|
Создано: 24 сентября 2007 19:23 · Личное сообщение · #11
А такое дело: надо найти именно саму ИАТ с границами? Потому что у меня в QuickUnpack при востановлении импорта ищутся переходники, похожие на импорт, и уже разбираются по отдельности. Имхо, для хитрожопых протов это понадёжней будет.
| Сообщение посчитали полезным: |
Ранг: 283.6 (наставник), 56thx Активность: 0.13↘0 Статус: Участник 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.02↘0 Статус: Участник
|
Создано: 25 сентября 2007 06:20 · Личное сообщение · #13
DillerInc пишет:
HoBleen пишет:
3) Твой вариант поиска конца ИАТ можно легко обмануть, подсунув между модулями вместо нулей мусор.
...ну,пока такого изврата я даже у StarForce не видел.
В следующей версии обязательно увидишь ну а если без приколов, то тот же стар может в ИАТ врезать свой вызов вм , и не гаронтированно что там не будет 8 нулей, и еще один вариант стар может сделать так чтоб начало ИАТ лежит в одной секции а ее хвост в другой, я не помню как именно тогда заканчивается ИАТ, но импереку длину ИАТ приходится вбивать ручками и в дампе править секции. (стар частенько так крутит секциями рандомайзом, так что учти)
| Сообщение посчитали полезным: |
Ранг: 283.6 (наставник), 56thx Активность: 0.13↘0 Статус: Участник 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.13↘0 Статус: Участник 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.07↘0 Статус: Участник
|
Создано: 25 сентября 2007 23:14 · Личное сообщение · #16
не могу пройти мимо %)
функция SE Handler должна быть cdecl
| Сообщение посчитали полезным: |
Ранг: 283.6 (наставник), 56thx Активность: 0.13↘0 Статус: Участник Author of GeTaOEP
|
Создано: 26 сентября 2007 08:56 · Личное сообщение · #17
__ пишет:
функция SE Handler должна быть cdecl
...ладно,ладно
Хотя и без того всё работает.Система-то,которая будет вызывать наш обработчик,наверно уж знает,где и что она должна за собой подчистить.
----- the Power of Reversing team | Сообщение посчитали полезным: |
Ранг: 115.1 (ветеран), 3thx Активность: 0.07↘0 Статус: Участник
|
Создано: 26 сентября 2007 12:34 · Личное сообщение · #18
в win9x не будет работать, в 2k/XP есть защита "от дурака" поэтому работает
| Сообщение посчитали полезным: |
Ранг: 303.7 (мудрец), 4thx Активность: 0.19↘0 Статус: Участник tPORt Manager
|
Создано: 26 сентября 2007 17:47 · Личное сообщение · #19
DillerInc
Диллер, ты псих. У старовцев есть чел, который шутшит все форумы реверсерские и докладывает разработчикам если что, если что, то защищает стар, лучше иди в приват.
| Сообщение посчитали полезным: |