Log in

View Full Version : Using Structure Offsets as Symbolic Constants in IDA


REBlog
October 19th, 2007, 20:27
I was analyzing Win32/Valla.2048 today, a file infector written in x86 Assembly. It keeps almost all of its variables (file handles, API function addresses, etc.) at the end of its section and it references these variables relative to EDI:

Code:
XOR:0040619A push 2
XOR:0040619C push 0
XOR:0040619E push dword ptr [edi+6EBh]
XOR:004061A4 call dword ptr [edi+602h]
XOR:004061AA mov [edi+6EFh], eax
XOR:004061B0 push 0
XOR:004061B2 push dword ptr [edi+6F7h]
XOR:004061B8 push dword ptr [edi+6EBh]
XOR:004061BE call dword ptr [edi+602h]



I would have liked to be able to create symbolic constants for these values, but there's no "New", "Add", etc. button in IDA's "Use standard symbolic constant" window:


http://malwareanalysis.com/CommunityServer/blogs/geffner/2006_03_17_1.gif


I probably could have created a Type Library for IDA, but this would have been more trouble than it was worth. So instead, I created a structure (named "v" for "Valla":

Code:
00000000 vstruc ; (sizeof=0x704)
00000000
codedb 1476 dup(?) ; string(C)
000005C4
moduleAddressOfKernel32 dd ?
000005C8
virtualAddressOfKernel32ExportTable dd ?
000005CC
pOriginalEntrypointMinusInfectorsEntrypoint dd ?
000005D0
originalEntrypointMinusInfectorsEntrypoint dd ?
000005D4
_lopen dd ?
000005D8 field_5D8
db 7 dup(?) ; string(C)
000005DF
_lread dd ?
000005E3 field_5E3
db 7 dup(?) ; string(C)
000005EA
_lwrite dd ?
000005EE field_5EE
db 8 dup(?) ; string(C)
000005F6
_lclose dd ?
000005FA field_5FA
db 8 dup(?) ; string(C)
00000602
_llseek dd ?
00000606 field_606
db 8 dup(?) ; string(C)
0000060E
FindFirstFileA dd ?
00000612 field_612
db 15 dup(?) ; string(C)
00000621
FindNextFileA dd ?
00000625 field_625
db 14 dup(?) ; string(C)
00000633
FindClose dd ?
00000637 field_637
db 10 dup(?) ; string(C)
00000641
GlobalAlloc dd ?
00000645 field_645
db 12 dup(?) ; string(C)
00000651
GlobalLock dd ?
00000655 field_655
db 11 dup(?) ; string(C)
00000660
GlobalFree dd ?
00000664 field_664
db 11 dup(?) ; string(C)
0000066F
GetTickCount dd ?
00000673 field_673
db 13 dup(?) ; string(C)
00000680
GetWindowsDirectoryA dd ?
00000684 field_684
db 21 dup(?) ; string(C)
00000699
GetSystemDirectoryA dd ?
0000069D field_69D
db 20 dup(?) ; string(C)
000006B1
GetFileAttributesA dd ?
000006B5 field_6B5
db 19 dup(?) ; string(C)
000006C8
SetFileAttributesA dd ?
000006CC field_6CC
db 19 dup(?) ; string(C)
000006DF
tickCount dd ?
000006E3 field_6E3 db ?
000006E4
dotdotdb 3 dup(?) ; string(C)
000006E7
starDotStardb 4 dup(?) ; string(C)
000006EB
hFile dd ?
000006EF
fileSize dd ?
000006F3
rvaOfNewSection dd ?
000006F7
offsetOfPEHeader dd ?
000006FB
pAllocatedMemory64K dd ?
000006FF
hMem dd ?
00000703
banner db ?
00000704
vends



This allowed me to then tell IDA to interpret the EDI offsets as structure offsets, making it much easier to analyze the virus:

Code:
XOR:0040619A push 2
XOR:0040619C push 0
XOR:0040619E push [edi+v.hFile]
XOR:004061A4 call [edi+v._llseek]
XOR:004061AA mov [edi+v.fileSize], eax
XOR:004061B0 push 0
XOR:004061B2 push [edi+v.offsetOfPEHeader]
XOR:004061B8 push [edi+v.hFile]
XOR:004061BE call [edi+v._llseek]



http://malwareanalysis.com/CommunityServer/blogs/geffner/archive/2006/03/17/11.aspx