![]() |
![]() |
![]() |
![]() |
![]() |
||||||||||
|
||||||||||||||
![]() |
#1
|
|||
|
|||
![]() Heres a tut I wrote quite awhile ago on unpacking a aspr'd target with ollydbg. Since andreageddon already wrote an indepth analysis for the essay section, i just decided to post mine here instead. some of you may have already read this, but it remained private for the most part.
----------------------------------------------------------------------- Unpacking a Delphi App Protected with ASProtect 1.23 RC 4 with OllyDbg by mMhCkB mmhckb@hotmail.com ----------------------------------------------------------------------- I've tried to make this tut generic so it can be posted on sites that do not allow the targets names and shit, but if anyone wants to know the target, or if you just have some questions, email me. I'm not offended by stupid questions. ----------------------------------------------------------------------- Required Tools: OllyDbg v1.09d with isdebugpresent plugin. ImpREC v1.6 with ASPR plugin. LordPE ----------------------------------------------------------------------- Uncheck all the boxes in the exceptions tab in the olly options. Set isdebugpresent plugin to Hide in olly. Shift+F9 til you reach: XOR DWORD PTR DS:[EAX],EAX POP DWORD PTR FS:[0] POP EAX CMP DWORD PTR DS:[11F7EB0],0 JE SHORT 011F3A13 PUSH 0C MOV ECX,11F7EB0 LEA EAX,DWORD PTR SS:[EBP-8] MOV EDX,4 CALL 011F0B40 PUSH DWORD PTR SS:[EBP-4] PUSH DWORD PTR SS:[EBP-8] MOV EAX,DWORD PTR SS:[EBP-C] CMP DWORD PTR DS:[EAX],0 JE SHORT 011F3A23 PUSH DWORD PTR DS:[EAX] PUSH DWORD PTR SS:[EBP-10] PUSH DWORD PTR SS:[EBP-14] RETN Set a breakpoint at the first RETN shift + f9 Now we are gona find the stolen bytes: Click on the ... button at the top of olly, right click and click the "Log to file" Go back to the CPU window and press CTRL + T Check "Command is one of these" and put " REP STOS BYTE PTR ES:[EDI] " in the box and click ok. Now press CTRL + F11. Click the run trace button again close log file. Now f8 into the RETN and Ctrl+A. You should be at something similar to JMP DWORD PTR DS:[BF52C4] Thats how aspr sets up its API's f7 into the JMP and f8 over the crap till the retn. f7 or f8 into the retn. Should be at something that looks like MOV DWORD PTR DS:[591668],EAX Dump with LordPE like normal. ( Click the process name in the top box, the right click the exe in the lower box and do a Dump -> Full ). Back in Olly, f8 through the crap til the retn. You will come out after the first call of the program. 0058C170 A4BA5800 DD Blah.0058BAA4 0058C174 00 DB 00 // OEP = 58C174 -- SAVE THE OEP 0058C175 00 DB 00 0058C176 00 DB 00 // This app has 12 Stolen bytes 0058C177 00 DB 00 0058C178 00 DB 00 0058C179 00 DB 00 0058C17A 00 DB 00 0058C17B 00 DB 00 0058C17C 00 DB 00 0058C17D 00 DB 00 0058C17E 00 DB 00 0058C17F 00 DB 00 0058C180 . E8 3FADE7FF CALL Blah.00406EC4 0058C185 . 8B1D 60095900 MOV EBX,DWORD PTR DS:[590960] // We come out here so scroll up Close OllyDBG and restart the app on its own Start imprec and load the process Now press iat auto search straight away. Now change the size to 1000 and click get imports. Open that import up and scroll to the bottom Click on Select invalid, then Trace Level 1. Now click show invalid again and trace with the ASPR plugin. Find the bottom valid API in the tree. Cut everything below it. Keep deleting from the bottom up if the bottom API is already in the list elsewhere. In imprec, replace RestoreLastError with SetLastError (both in kernal32) Look in kernel32 for GETACP, underneith it is an unresolved one. This is always "FreeResource" Click show invalid again and cut thunks Fix the oep with lordpe. Find out what the program was made with using PEiD. Open the fixed exe in Olly You should be at the shit with the 00's. Our stolen bytes. Open up the log we made Search for RETN 8 Will have to disassemble some different exe's and get used to the opening patterns, the app that we used during this tutorial was delphi. Scroll down until you reach PUSH EBP Thats our first shit beings the app is delphi Remember, in this example, we have 12 bytes. It will be: PUSH EBP 1 Byte MOV EBP,ESP 2 Bytes Another shit MOV EAX, Something 5 Bytes Assemble the first two into the exe (Hit spacebar) Our example logfile. 0120D971 Main PUSH EBP 0120D972 Main JMP SHORT 0120D975 0120D975 Main POP DWORD PTR SS:[ESP] 0120D979 Main MOV EBP,ESP EBP=0012FFC0 0120D97B Main SUB ESP,10 We know MOV EAX, ADDR = 5 bytes + Our Push and MOV we already found, we've used 8 total bytes already. Meaning we are still missing 4. SUB ESP,10 is 3 bytes so put it as the next one. Lets look some more: 0120D981 Main ADD WORD PTR DS:[120D98B],7AF4 0120D98A Main PREFIX REP: 0120D98F Main ADD WORD PTR DS:[120D999],8F70 0120D998 Main PREFIX REPNE: 0120D99C Main LEA ESP,DWORD PTR SS:[ESP+ESI-1] 0120D9A0 Main SUB ESP,ESI We are missing 6 bytes and 5 will be taken from the mov eax, so we are missing 1. If we look there, it cant be any of them. The ADD, PREFIX and LEA is aspr crap SUB ESP, ESI = 4 bytes ... too big 0120D9A2 Main JMP SHORT 0120D9A7 0120D9A7 Main LEA ESP,DWORD PTR SS:[ESP+5A] 0120D9AB Main LEA ESP,DWORD PTR SS:[ESP-5D] 0120D9AF Main JMP SHORT 0120D9B4 0120D9B4 Main PUSH EBX PUSH EBX = 1 byte so, we take that. Now we need to find what is moved into EAX. So scroll further down through the log, looking at all the values of EAX. 0120DB00 Main ROL EAX,8D EAX=757295B8 0120DB03 Main XCHG EAX,EBX EAX=7FFDF000, EBX=757295B8 757295B8 is way out of range, so futher down: 0120DB34 Main ADD EAX,4BF92A21 EAX=0058BACC 58BACC sounds good to me so last one is MOV EAX, 0058BACC. Now lets save em: right click, goto copy to executable, then choose All modifications. Click "Copy All" and a new window pops up with all the changes in grey. Right click and save the file. Run the newly fixed exe. If you're lucky, it might work and you're done, but odds are, there are dips (Pointers used by ASPR that are no longer valid in the unpacked exe. ) Open up the newly fixed exe in olly and f8 over the calls till it crashes. Restart and trace into the call it crashed at. Keep repeating until you're in the call that actually crashes. Replace the first line of this call (Generally small call starting with PUSH EBP) with RETN and continue tracingtil you find the next call that crashes. These calls that crash us are actually leading to RaiseException, so, by doing the RETN, we just bypass it. If there are any more calls like this, do the same RETN trick. Keep tracing over til you find the next one that will crash you, it may look like this: 00579E54 55 PUSH EBP 00579E55 |. 8BEC MOV EBP,ESP 00579E57 |. 51 PUSH ECX 00579E58 |. 53 PUSH EBX 00579E59 |. 8B05 62724000 MOV EAX,DWORD PTR DS:[407262] ; <&kernel32.GetModuleHandleA> 00579E5F |. 8B18 MOV EBX,DWORD PTR DS:[EAX] 00579E61 |. FF33 PUSH DWORD PTR DS:[EBX] 00579E63 |. 895D FC MOV DWORD PTR SS:[EBP-4],EBX 00579E66 |. 8F03 POP DWORD PTR DS:[EBX] 00579E68 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00579E6B |. 5B POP EBX 00579E6C |. 59 POP ECX 00579E6D |. 5D POP EBP 00579E6E . C3 RETN You will see this one a lot. What it basically does is move the emulated api into the shit, but we dont have emulated api's no more. So just change the PUSh to a RETN. Restart the app once all the crash calls have been fixed. Click on the "/" button thats patches press space bar on all of the lines. Search the program for things that no longer work or that crash it. In my target here, one of the menu items originally brought up a message box with the text "Filelist is empty. Do you still want to build ISO?", the newly fixed exe however does nothing. Open up the even newer fixed exe in Olly and right click in the CPU window. Search for -> All referenced text strings. Search for the string. Scroll up and find where the function starts and trace here in the fixed and the packed app. One will most likely take a jump while the other doesn't or some shit. My function looked like this: 00585C28 $ 55 PUSH EBP 00585C58 . E8 5B3FFFFF CALL dumped_f.00579BB8 // Lets look in this call. 00585C5D . 837D F8 00 CMP DWORD PTR SS:[EBP-8],0 00585C61 . 75 0A JNZ SHORT dumped_f.00585C6D // Packed app jumps here Lets look inside the call 00579BB8 /$ 53 PUSH EBX 00579BB9 |. 8BD8 MOV EBX,EAX 00579BBB |. 8BC3 MOV EAX,EBX 00579BBD |. 8B15 F8005900 MOV EDX,DWORD PTR DS:[5900F8] 00579BC3 |. E8 48B0E8FF CALL dumped_f.00404C10 00579BC8 |. 5B POP EBX 00579BC9 . C3 RETN In the packed app, MOV EDX,DWORD PTR DS:[5900F8] is a pointer to your computers machine id. But in our unpacked app, the PTR no longer exists. Set a breakpoint there so we can remember it. Now scroll with olly to the bottom till u see some unused space, 0's and shit. 0058C28C . 44 72 6F 70 54>ASCII "blah blah" 0058C29C . 29 00 ASCII ")",0 0058C29E 00 DB 00 0058C29F 00 DB 00 0058C2A0 00 DB 00 0058C2A1 00 DB 00 From here on, safe every change you make and its address somewhere. At 0058C29F, select enough bytes to hold your name. Right click -> binary -> edit. Type in your name or some other random bullshit. Ctrl+A. Lets go back to where we were, the place we set the breakpoint. In olly u have the CPU windows, a middle window, and the hex wnidow. If u click on that line u will see in the middle window DS:[5900F8]= Right click and follow address in dump so we can change the pointer. The address must be in reverse order, so select them 4 bytes. Right click, binary edit I stuck my name in at 0058C2A0 but yours will most likely be different. so, enter: A0, C2, 58, 00 The DS:[5900F8]= should now say your name. Scroll up/down a bit and you may see another call similar to that one 00579B88 /$ 53 PUSH EBX 00579B89 |. 8BD8 MOV EBX,EAX 00579B8B |. 8BC3 MOV EAX,EBX 00579B8D |. 8B15 F0005900 MOV EDX,DWORD PTR DS:[5900F0] 00579B93 |. E8 78B0E8FF CALL dumped_f.00404C10 00579B98 |. 5B POP EBX 00579B99 . C3 RETN Lets fix this pointer too so do the same. Run the app (F9) and it should all work fine now. Restart the app make the changes to the CPU window again. Copy to executable -> All modifications. Save file. Blah. Open up this newest exe in Olly and do the Hex Dump changes. Right click in the Dump, Copy to executable, Save file. You're know done!!!! Woohoo. We had to restart and change that shit again without the program running because otherwise the variables are already unloaded into memory and the unpacked exe wont run on anyone elses machine. Good luck unpacking shit from here on out, mMhCkB Hundreds of thousands of thanks to my good buddy who's taught me every thing I know about unpacking. |
#2
|
|||
|
|||
![]() Hi mMhCkB,
I have been trying for a while now to get a working dump of Gene6 FTP Server, which is packed with ASProtect 1.23 RC 4 versions The lastest ftp verions is 3.0.2 build 39, i have found the following from your tute- OEP: 4915C8 Stolen bytes: 558BEC83EC10B828104900 And also i have resolved imports with imprec, next i try to place RETN in aspr dips, but not all the exceptions in my dump are in small funtions starting push ebp, i placed RETN anyways, but i dont get a working dump ![]() -- bedrock |
#3
|
|||
|
|||
![]() aspr 1.23 is an old version. Could you please explain how to unpack version 1.31
instead, and specifically, which new obstacles i may face when attacking it. thank you! |