Распаковка нового AsProtect-а
подопытную программу можно взять тут. версия АсПротекта или 1.3бета, или 1.23RC-какой-то-там. по поводу детектинга SoftIce. в подробности вдаваться не было времени. однако, IceDump под W9x сайс уже не прячет. под NT прячет последний IceExt. а в любом случае BPX MapViewOfFile вообще ни к чему хорошему не приведет ;)
итак, начнем. OEP находится старинным методом - bpm esp-4. остановимся на "popad ; push eax ; ret ". сразу можно сдампить прогу. .0040168C: jmps .00040169E ----- (1) .0040168E: bound di,[edx] .00401691: inc ebx .00401692: sub ebp,[ebx] .00401694: dec eax .00401695: dec edi .00401696: dec edi .00401697: dec ebx .00401698: nop .00401699: jmp 00050B736 .0040169E: mov eax,[0050A08B] .004016A3: shl eax,002 .004016A6: mov [0050A08F],eax .004016AB: push edx .004016AC: push 000 .004016AE: call .00050871E ----- (2)Поскольку программа наша написана на BCB, функция .50871E явно GetModuleHandleA. смотрим дальше. .0050871E: call d,[00BBCFC4] .00508724: jmp d,[00BBD0F8] .0050872A: jmp d,[00BBD14C] .00508730: jmp d,[00BBD468] .00508736: jmp d,[00BBD474]ого-го. вместо 00BBxxxx вообще-то должны быть адреса IAT-овской ячейки для конкретной функции. еще вместо JMP аспр понавставлял CALL. глянув туда, где должна быть IAT (пятая по счету секция) -- там сплошной мусор, IAT-ом и не пахнет. таким образом, делаем заключение, что IAT вообще не используется, а вызовы функций перенаправляются сразу на переходники. одним ImpRec-ом тут, естесственно, ничего сделать нельзя. чтобы разобраться, где и как генерируются адреса переходников, ставим BPM 50871E+2. отловим уже при записи адреса переходника в [508720]. потрассировав, увидим, что для получения адреса функции вызывается GetProcAddress. только не он сам, а его переходник. затем вызывается функция, которая по оригинальному адресу функции возвращает адрес готового переходника. хочется сказать, что отлавливать "оригинальные адреса функций" нужно не в одном месте, а в трех. в первом случае адрес возвращается по имени функции, во втором по ординалу, в третьем еще как-то. у меня не было времени на поиск изысканных методов как вытащить адреса функций. я написал dll-ку с функциями для каждого из трех методов. procedure P; cdecl; var IATRVA, ProcAddr, DllBase: dword; t: text; p: pchar; begin asm mov IATRVA, ebx // адрес, куда будет помещен адрес переходника mov ebx, [ebp+30h] // имя функции mov p, ebx mov ebx, [ebp+2Ch] // ModuleHandle библиотеки, из которой импортируется функция mov DllBase, ebx end; {$I-} AssignFile(t, 'import.txt'); append(t); writeln(t, Format('%x %x %s',[IATRVA, ProcAddr, string(p)])); closefile(t); end;затем в теле аспровой функции получения адреса переходника пишем: pushad push имя нашей длл call LoadLibraryA push имя нашей функции в длл push eax call GetProcAddress call eax ; вызываем функцию popad jmp GetProcAddressGetProcAddress после popad сделает все вместо аспровой функции. а до этого мы сделали все что нам надо. таким образом в файле import.txt будет инфа о части функций. примерно то же самое нужно сделать и с двумя другими функциями получения адресов. затем, я накидал прожку, которая составляет полностью весь IAT, поправляет в программе JMP/CALL [аспр] строго на JMP [IAT offset]. брякнувшись на OEP загрузил свой IAT по адресу 552000 и подсунул ImpRec-у. не хватало 2-х функций: GetProcAddress и FindResourceA. ручками поправили. Fix Dump. фуф. вроде все. ан нет. при запуске программы вылетает exception. после отладки выясняется, что аспр перекинул пару функций из программы в свое тело и запускал их от туда следующим методом: .004D2268: push 000B7CA44 .004D226D: retn .................................. .004D3110: push 000B7CB2D .004D3115: retnопять лезем в запакованный .ехе-шник и выцепляем функции, вставив ее куда-нибудь в область с кучей нулей. запускаем. ура. работает :-) по-хорошему надо бы сваять утиль для получения импорта. но совершенно нет времени. дерзайте те, кому время позволяет. на этом всё. приветы летят к //PRA, //UOFG, VaG, Zwei и всем-всем-всем ;-) (q) 26 oct 2003, deus [ deus@hotbox.ru ]
|