Environment Configuration#
The overall architecture of remote debugging is shown in the following figure
Since the debugger cannot run on Windows on a Mac, remote debugging can be used to debug through a Mac.
First, copy the packed file and remote debugging service file to the TARGET (win10)
machine, and the remote debugging service file is located in the dbgsrv directory.
The final structure of TARGET (win10)
is as follows
The packed program is packed using upx and is a 32-bit program.
Remote Debugging#
Before remote debugging, analyze the packed program PACKED_PRACTICA_1.EXE
on a Mac (ida7.0) for partial analysis, check MANUAL LOAD for manual loading, and load all sections of the file.
Before running the debugger, the IDA loader will go to the entry point of the packed program.
Program entry
Note: The database file IDB cannot be renamed
Run the win32_remote.exe remote debugging server on TARGET (win10)
, and specify the IP address with -i.
Select Remote Windows debugger
as the debugger.
In Process options, enter the IP address and port of TARGET (win10)
in Hostname, enter the absolute path of the packed program in Application and Input file, enter the directory path in Directory, and click ok after the configuration is complete.
Open the debugger menu and select Start process, the program will pause at the entry point after the debugging starts (modified: you need to set a breakpoint at 0x638ec to pause here).
The executable file has been randomized, so the address of each execution will change. Therefore, the dumping and rebuilding of the IAT must be completed in the same run, and the program cannot be closed halfway.
Open the segments tab and observe the first code section after the header. The start address of this section is 631000 and the end address is 238000.
Finding OEP#
The first method is to try the text search function to search for the popad or popa instruction. In this program, a popa instruction can be found.
From the figure, it can be seen that the address 0x63146e is the OEP.
The second method is to find the OEP by covering the first section with an execution breakpoint learned before.
Double-click on the first section in the segment view to jump to 0x631000 and view the section data. The address is randomized, and the base address is not 0x401000, but the memory occupancy is 0x7000. The upx0 section is from 0x631000 to 0x638000, and the difference is 0x7000 bytes.
Set a breakpoint at the starting point of the upx0 section by pressing F2, which is 0x601000 here, and the breakpoint size is 0x7000.
Delete other breakpoints and leave only this breakpoint, and press F9 to start debugging.
The program pauses at this point, and it is confirmed that it is consistent with the previous OEP position, and then delete this breakpoint and remove the red background.
Click Reanalyze program in the lower left corner of the interface to reanalyze the program.
The content after OEP is recognized by IDA as part of STUB, so it is not marked with sub_
but with loc_
.
Dumping and IAT Rebuilding#
After finding the OEP, start dumping and rebuilding the IAT. First, check the file base address and the highest address.
Here, the file base address is 0x630000, and the highest address is 0x63B000. Take out the dumping script file, modify the addresses in the file, and then load and run the script.
The script is as follows:
import idaapi
import idc
import struct
start_ea = 0x630000
end_ea = 0x63b000
step = 4 # Each address occupies 4 bytes
file_path = "dump.bin"
with open(file_path, "wb") as f:
for ea in range(start_ea, end_ea, step):
# Read 4 bytes of data at the specified address and convert it to little-endian byte order
bin_data = struct.pack("<L", idaapi.get_32bit(ea))
f.write(bin_data)
After running, a dump file is generated (the script file runs on a Mac, so the dump file is also generated on the Mac).
Copy the dump.bin file to Windows and open it with peeditor.
Right-click on each section and select dumpfixer, and then change the .bin file to an .exe file. The effect is as follows:
Open the dump.exe file with scylla, and load the packed program process.
Enter the OEP address, which is 0x63146e here, and then click IAT Autosearch and Get Imports. An unrecognized API function is found.
Add the base address to the API address, 0x630000+0x20d4=0x6320d4, go to the hexadecimal view, and it is not part of the IAT.
Switch to the disassembly view to view the references at this location, and the content is as follows:
Press x to display 2 references.
The address pointed to by 0x6320d4
only returns the RET instruction, as follows:
The address pointed to by 0x6320d4
is a fixed address within the program, and it is only a RET instruction, not the referenced API function. Therefore, it can be deleted. In Syclla, right-click on the API function error and select CUT THUNK to delete it from the IAT.
After deletion, it is as follows:
Finally, click Fix Dump to rebuild the IAT for dump.exe, and finally generate the dump_SCY.exe executable program.
If you run dump_SCY.exe at this time, it will still flash a black screen and exit.
Canceling Random Base Address#
Because the addresses generated at runtime other than the IAT are not redirected because they are always changing, this randomness needs to be eliminated. Open IDA, load the dump_SCY.exe file, use Manual Load to load the pe header section, and then go to this section.
In the header, find the Dll characteristics, and change its value to 0.
Open the Edit menu, select patch program, and change the word to 0.
Click ok, and then use apply patches to input file to save the changes back to the executable file.
At this moment, running dump_SCY.exe
again can run successfully, indicating that the unpacked file is executed successfully.