Finding an unpacking service9/22/2023 ![]() Then there is "stolen code" approach which makes it harder to find and recover OEP. For example, some packers don't fully resolve imports initially but put jumps to stubs that resolve import on first call and then patch it so it goes directly to the target next time. Now, there are many variations and tricks not covered by the above steps. I don't do this step as I rarely need to run the unpacked file but in general you usually need to fix up the PE header so that offsets to the section's code in file match those in the dump. In IDA, you should also apply a compiler FLIRT signature if you recognize the compiler used. This is optional but it may be useful to remove the remains of the packer code that would only distract you. Putting a read BP on kernel32's export table might help here. This however won't work with packers that use manual import resultion using the export directory. Usually the start and the end of the table is obvious.ĭuring unpacking, set a breakpoint on GetProcAddress and see where the results are written. You can use either renimp.idc script or UUNP "manual reconstruct feature" (see here).įor finding import table there are two tricks I sometimes use:įollow some calls in the startup code at OEP to find external APIs and this should lead you to the import table. You just need to find the import table and rename the pointers according to the functions they are currently pointing to (this should be done while debugger is active). I'm not very familiar how it's done in Olly or other debugger, but AFAIK you need to use a tool like ImpREC on your dump and a copy of the process in memory. One thing to keep in mind here is that if the packer used dynamically allocated memory, you need to mark it as "loader" so it gets included in the snapshot. If you're using IDA, you don't actually need to dump the file into a separate file - it's enough to take a memory snapshot that would copy the bytes from memory to the database so you can analyze them later. This won't get you the exact OEP, but you can usually go back the callstack and find it more or less easily. Set breakpoints on common APIs used by startup code, e.g. IDA allows you to set such a breakpoint, and I think OllyDbg too. If during tracing you can identify memory where the unpacked code is being written, set a page execution breakpoint on that memory range - it will trigger after the jump. If the packer saves the original registers before unpacking, set a hardware breakpoint on their location in the stack - this way you'll break right when they're restored before jumping to OEP. ![]() Or you may recognize the code at OEP if you're familiar with the entrypoints produced by different compilers. ![]() Sometimes the jump to OEP is obvious when it follows a chunk of looping code and there's nothing reasonable-looking after it. Using a VM or an emulator here usually helps against most of them. They may employ timing checks ( rdtsc), exception-based control transfer, using debug registers for calculations etc. This is not difficult with simple packers but might be tricky with the more advanced ones. Trace the code, possibly evading or bypassing anti-debugging checks. Unpacking a generic wrapping packer or cryptor usually involves the following steps: 1. ![]()
0 Comments
Leave a Reply.AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |