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

 eXeL@B —› Программирование —› Определение полного размера функции
Посл.ответ Сообщение


Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 22 апреля 2006 21:32
· Личное сообщение · #1

Зацените и потестируйте алгоритм определения полного размера функции.

PS: Тестить надо на релиз версии т.к. в отладочной версии (у меня по крайней мере) студии 2003 и 2005 вызывают функцию GetFunctionSize через таблицу прыгов: call GetFunctionSize -> jmp GetFunctionSize -> Function Body, а должно быть сразу call GetFunctionSize -> Function Body т.к. неправильно вычисляется адрес фунции, вместо адреса функции получаем адрес этого прыга.

Фрагмент таблицы прыгов для тех кто не верит:
@ILT+580(?GetFunctionSize@@YAJPAX@Z):
00411249 E9 72 08 00 00 jmp GetFunctionSize (411AC0h)
@ILT+585(_IsBadWritePtr@8):
0041124E E9 71 1C 01 00 jmp IsBadWritePtr (422EC4h)
@ILT+590(__RTC_InitBase):
00411253 E9 88 11 00 00 jmp _RTC_InitBase (4123E0h)
@ILT+595(_IsBadReadPtr@8):
00411258 E9 6D 1C 01 00 jmp IsBadReadPtr (422ECAh)
@ILT+600(__CrtSetDumpClient)


afec_22.04.2006_CRACKLAB.rU.tgz - LenDissam+Call.cpp

-----
have a nice day





Ранг: 199.6 (ветеран), 12thx
Активность: 0.10
Статус: Участник
www.uinc.ru

Создано: 22 апреля 2006 21:49
· Личное сообщение · #2

Работать будет не всегда, даже если строить карту кросрефов.
Простейший пример:

test_proc:
mov eax, [esp+4]
cmp eax, 2
jge bad_param
jmp d,[eax*4+jmp_table]
jmp_table:
dd offset ex0
dd offset ex1
bad_param:
xor eax, eax
retn
ex0:
mov eax, 123
retn
ex2:
mov eax, 234
retn





Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 22 апреля 2006 22:05 · Поправил: Nimnul
· Личное сообщение · #3

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

-----
have a nice day




Ранг: 450.1 (мудрец)
Активность: 0.260
Статус: Участник

Создано: 22 апреля 2006 22:30
· Личное сообщение · #4

как раз MS VC с определенными ключами компиляции такой код, что привел DrGolova, и генерит ;)




Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 23 апреля 2006 06:06
· Личное сообщение · #5

Asterix

ключи в студию

-----
have a nice day




Ранг: 450.1 (мудрец)
Активность: 0.260
Статус: Участник

Создано: 23 апреля 2006 06:14 · Поправил: Asterix
· Личное сообщение · #6

типа таких
/GX /Ox /Ot /Og /Oi /Gf

и скомпили функцию типа DlgProc или посложнее




Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 24 апреля 2006 07:37 · Поправил: Nimnul
· Личное сообщение · #7

Можно парсить jmp на предмет близости прыжка, но еще раз повторюсь что функция написанна для нормального кода, и может использоваться например для составления бинарников. А что касается извратного кода то может быть например такой:

test_proc:
mov eax, [esp+4]
cmp eax, 2
jge bad_param
mov eax, ex0
push eax
retn
bad_param:
xor eax, eax
retn
ex0:
mov eax, 123
retn
ex2:
mov eax, 234
retn

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

-----
have a nice day





Ранг: 199.6 (ветеран), 12thx
Активность: 0.10
Статус: Участник
www.uinc.ru

Создано: 24 апреля 2006 12:42 · Поправил: DrGolova
· Личное сообщение · #8

> дальние прыжки jmp, не учитываются при анализе, по причине: они не используются для переходов внутри одной

С чегобы это? Размер функции не может быть больше 127 байт?

> Только непонятно одно кто будет делать это в своей программе и самое главное зачем?

То что ты написал, может получиться токлько екли кто-то спецально сделает ассемблерную вставку.
То что я написал, генерируется компилятором, на любом достаточно большом switch, например:


int get_cmd_len(unsigned char* cptr)
{
unsigned char* optr = cptr;

switch( *cptr++ )
{
case 0x90: /* nop */
case 0x50: /* push reg */
case 0x51:
case 0x52:
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
break;
case 0xB8: /* mov reg, imm32 */
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF:
cptr += 4;
break;
default:
return(0);
}

return(cptr - optr);
}





Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 25 апреля 2006 20:52 · Поправил: Nimnul
· Личное сообщение · #9

С чегобы это? Размер функции не может быть больше 127 байт?

Вобще то есть команды условного перехода 0F 8x, они адресуют signet dword адрес. Мой алгоритм учитыет их. И у меня компилятор на больших кейсах вставляет именно эти условные прыги, а джампы в кейсах повидимому используются только тогда когда растояние между прыжками больше двух гигов, или выкинь свой компилятор .
 

-----
have a nice day





Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 25 апреля 2006 21:30
· Личное сообщение · #10

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

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

-----
EnJoy!





Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 26 апреля 2006 06:23 · Поправил: Nimnul
· Личное сообщение · #11

а джамп для обычного безусловного перехода?

А что с ним не так?

к тому же редкий выход (в случае ошибки и т.п.) может быть вообще выброшен далеко за пределы функции

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

от непонимания выбрасывание компилятора тебя не спасёт

поясни эту фразу
 
 

-----
have a nice day





Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 26 апреля 2006 08:25
· Личное сообщение · #12

обычный jmp не обязан укладываться +-127 байт

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

скомпилируй майкрософтовским cl.exe (с оптимизацией по скорости) какие-нить функции с несколькими выходами, а потом глянь их в дизассемблере! увидишь, что куски некоторых ф-ций оторваны от основного тела, потом управление из них передаётся обратно, это и есть т.н. function chunk
не путай выход при ошибке с функцией по обработке ошибок!

Jupiter пишет:
от непонимания выбрасывание компилятора тебя не спасёт

Nimnul пишет:
поясни эту фразу

поясняю:
если ты выкинешь компилятор, который генерит код, не понятный тебе, то сам факт выбрасывания не поможет тебе в понимании. так понятно?

-----
EnJoy!





Ранг: 218.9 (наставник), 42thx
Активность: 0.160
Статус: Участник
dotnet

Создано: 26 апреля 2006 12:08
· Личное сообщение · #13

Jupiter пишет:

обычный jmp не обязан укладываться +-127 байт


А я где то говорил об обратном?

скомпилируй майкрософтовским cl.exe

Скомпилируй сам пожалуйста и приатач, будет интересно глянуть.

если ты выкинешь компилятор, который генерит код, не понятный тебе, то сам факт выбрасывания не поможет тебе в понимании. так понятно?

С чего ты взял что есть код непонятный мне? остальное коментировать небуду.
 

-----
have a nice day



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


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