You've probably heard about Microsoft PowerShell. This small note will show you how to analyze (well at least start to analyze) Windows PE executable files with just use of PowerShell.
I suggest that you open these two sites:- YATES` PE NOTES
- and famous An In-Depth Look into the Win32 Portable Executable File Format by Matt Pietrek
- you can also download Microsoft PE and COFF specification if you really want.
- PS > $file=$(ls axe2.exe)
- PS > $stream=$file.OpenRead()
- PS > $x=new-object -TypeName Byte[] -ArgumentList $stream.Length
- PS > $stream.Read($x, 0, $stream.Length)
- PS > Function dword($x, $b) { $x[$b] + $x[$b+1]*0x100 +
- >> $x[$b+2]*0x10000 + $x[$b+3]*0x1000000; }
- >>
- PS > Function word($x, $b) { $x[$b] + $x[$b+1]*0x100; }
- PS > $PE = (dword $x 0x3c)
- PS > $ep = (dword $x ($PE + 0x28))
- PS > $sect_no = (word $x ($PE + 0x6))
- PS > $opt_hdr_size = (word $x ($PE + 0x14))
- PS > $dd_off = ($PE + $opt_hdr_size + 0x18)
Because section-names (8-bytes long) in packed files are often unreadable, I'll be writing out just hex-value of first four bytes like this:
- ([long](dword ...)).toString("x8");
- PS > Function name($x, $b) {
- >> $n="";
- >> for ($l=0; $l -lt 8; $l++) {
- >> $n+=[char]$x[$b+$l];
- >> }
- >> $n
- >> }
- >>
- PS > $k=$dd_off; for ($j=0; $j -lt $sect_no; $j++) {
- >> (name $x $k) + " " + ([long](dword $x $k)).toString("x8");
- >> $k+=0x28 }
- >>
- for ($k=$dd_off, $j=0; $j -lt $sect_no; $j++,$k+=0x28)
ok so now the same, but we will print some more useful stuff:
- PS > $k=$dd_off+0xC; for ($j=0; $j -lt $sect_no; $j++) {
- >> " [+" + ($j+1) + "] vaddr: " + ([long](dword $x $k)).toString("x8") +
- >> " EP:" + $EP.toString("x8") +
- >> " vend: " + ([long](dword $x ($k - 0x4)) + [long](dword $x $k)).toString("x8") +
- >> " (vsize: " + ([long](dword $x ($k - 0x4))).toString("x8") +")";
- >> $k+=0x28
- >> }
- >>
- [+1] vaddr: 00001000 EP:00001018 vend: 0006d000 (vsize: 0006c000)
- [+2] vaddr: 0006d000 EP:00001018 vend: 000b5000 (vsize: 00048000)
- [+3] vaddr: 000b5000 EP:00001018 vend: 000b6000 (vsize: 00001000)
EP - sect_vaddr + physical_offset (0x14 bytes from beginning of each dd entry)
but we've got to remember that physical offset should be file aligned (file alignement in optional header, 0x3c from beginning of PE). Let's call this fal, now phisical EP will be:
EP - sect_vaddr + ((physical_offset/fal)*fal)
there is also object alignment, but we won't bother about that. fal is usually 512 bytes that is 0x200, you can check your value with:
- PS > (dword $x ($PE + 0x3c))
- PS > $phys_off = (dword $x ($dd_off + 0x14))
- PS > $phys_ep = $EP - (dword $x ($dd_off + 0xc)) + [int]($phys_off/0x200)*0x200
At the end let's read some bytes from the beginning of our ep:
- $n=""; for ($j = 0; $j -lt 16; $j++) { $n += ([int]$x[$phys_ep + $j]).toString("x2") + " " } $n
Ok So now I'm waiting until someone will make disasembler for PSH :)
gim.org.pl is down






