如果在根目录下如果ID是数字是资源类型:
1:cursor
2:bitmap
3:icon
4:menu
5:dialog
6:table
7:fontdirectory
8:font
9:accelerators
10:unformattedresourcedata
11:messagetable
12:groupcursor
14:groupicon
16:versioninformation
任何其他数字都是自定义任何带类型名字资源类型都是自定义更深层话ID是资源ID或者资源名字
如果再深入层ID必须是数字它是特定资源例子语言ID例如可以具有区别本地化语言对话框他们使用统资源ID系统会选择基于线程地域加载对话框反过来反应用户区域设置如果对于线程本地没有资源发现系统首先试图发现中立语言为资源区域如果还不能够发现带有最小语言ID例子将被使用解码语言ID拆分为主语言ID和子语言ID使用宏PRIMARYLANGID和SUBLANGID,分别是0-910-15其值定义在"winresrc.h".
语言资源只被加速键对话框菜单串表支持其他资源类型必须是LANG_NEUTRAL/SUBLANG_NEUTRAL.
要找出资源目录下级目录是否是另个目录检查偏移量高位如果置1其余31位是从资源原始数据开始到下个目录偏移量格式还是IMAGE_RESOURCE_DIRECTORY后面跟着IMAGE_RESOURCE_DIRECTORY_ENTRYs项目.
如果高位清0偏移量是从节开始到资源原始数据描述结构(个IMAGE_RESOURCE_DATA_ENTRY)偏移量个IMAGE_RESOURCE_DATA_ENTRY包括
IMAGE_RESOURCE_DATA_ENTRYSTRUCT
OffToDatadd?
Size1dd ?
CodePagedd ?
Reserveddd ?
IMAGE_RESOURCE_DATA_ENTRYENDS
32位'OffToData'从资源节开始到原始数据偏移量32位数据大小Size32位'CodePage'和32保留
原始数据格式依赖于资源类型任何串资源都是UNICODE格式
重定位relocations
-----------
最后个数据目录是重定位基重定位目录被IMAGE_DIRECTORY_ENTRY_BASERELOC指向典型包括个自己节名字是".reloc"以及IMAGE_SCN_CNT_INITIALIZED_DATA,IMAGE_SCN_MEM_DISCARDABLE和
IMAGE_SCN_MEM_READ位集合
如果映象没有被加载器调入优先地址则该数据被加载器使用这种情况下给链接器填入地址无效了加载器必须修复用于静态变量绝对地址串等
IMAGE_BASE_RELOCATIONSTRUCT
VirtualAddressdd ?
SizeOfBlockdd ?
IMAGE_BASE_RELOCATIONENDS
重定位目录是系列块每个块包括重定位信息针对4K映象个块起始于个'IMAGE_BASE_RELOCATION'结构包括32位'VirtualAddress'和32位'SizeOfBlock'.随后是实际重定位数据每个都是16位'VirtualAddress'是本块要应用基地址'SizeOfBlock'是整个块大小后面重定位数目是('SizeOfBlock'-(IMAGE_BASE_RELOCATION))/2重定位信息以VirtualAddress'=0IMAGE_BASE_RELOCATION结构结束
每个16位重定位信息包括低12位重定位位置和高4位重定位类型要得到重定位RVA,IMAGE_BASE_RELOCATION''VirtualAddress'需要加上12位位置偏移量.类型是下列的:
IMAGE_REL_BASED_ABSOLUTE(0)使块按照32位对齐位置为0
IMAGE_REL_BASED_HIGH(1)高16位必须应用于偏移量所指高字16位
IMAGE_REL_BASED_LOW(2) 低16位必须应用于偏移量所指低字16位
IMAGE_REL_BASED_HIGHLOW(3)全部32位应用于所有32位.
IMAGE_REL_BASED_HIGHADJ(4)需要32位高16位位于偏移量低16位位于下个偏移量元素组合为个带符号数加上32位个数然后加上8000然后把高16位保存在偏移量16位域内
IMAGE_REL_BASED_MIPS_JMPADDR(5) Unknown
IMAGE_REL_BASED_SECTION(6) Unknown
IMAGE_REL_BASED_REL32(7) Unknown
举例:
0x00004000 (32bits,startingRVA)
0x00000010 (32bits,chunk)
0x3012 (16bitsrelocdata)
0x3080 (16bitsrelocdata)
0x30f6 (16bitsrelocdata)
0x0000 (16bitsrelocdata)
0x00000000 (nextchunk'sRVA)
0xff341234
第块描述重定位起始于RVA0x4000长度16字节头用去8字节个重定位用2个字节总共(16-8)/2=4个重定位第个重定位被用于0x4012下个重定位于4080,第 3个定位于0x40f6.最后个无用最后个结束附录:Appendix:helloworld
---------------------
Theprogramwillbetheequivalentof
#<stdio.h>
(void)
{
puts(hello,world);
0;
}
用Win32代替Cruntime: #STD_OUTPUT_HANDLE-11UL
#hello"hello,world
"
__declspec(dllimport)unsignedlong__stdcall
GetStdHandle(unsignedlonghdl);
__declspec(dllimport)unsignedlong__stdcall
WriteConsoleA(unsignedlonghConsoleOutput,
constvoid*buffer,
unsignedlongchrs,
unsignedlong*written,
unsignedlongunused
);
unsignedlongwritten;
voidstartup(void)
{
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),hello,(hello)-1,&written,0);
;
}
汇编语言 startup:
;参数WriteConsole,逆向
6A00 push 0x00000000
68???????? push off_written
6A0D push 0x0000000d
68???????? push offhello
;参数GetStdHandle
6AF5 push 0xfffffff5
2EFF15???????? call dwordptrcs:__imp__GetStdHandle@4
;resultislastparameterforWriteConsole
50 push eax
2EFF15???????? call dwordptrcs:__imp__WriteConsoleA@20
C3 ret
hello:
68656C6C6F2C20776F726C640A "hello,world
"
_written:
00000000
下面是链接器:我们需要找出WriteConsoleAandGetStdHandle.他们在"kernel32.dll".此为输入库部分我们现在生成可执行文件问号在后面被找出
DOS-stub,起始于0x00x40字节:
00|4d5a0000000000000000000000000000
10|00000000000000000000000000000000
20|00000000000000000000000000000000
30|00000000000000000000000040000000
只是个头前面带有签字"MZ"后面是e_lfa指针然后是PE签名起始于0x400x4字节:50450000
下面是文件头起始于0x44,0x14字节:
Machine 4c01 ;i386
NumberOfSections 0200 ;codeanddata
TimeDateStamp 00000000;whocares?
PoerToSymbolTable 00000000;unused
NumberOfSymbols 00000000;unused
SizeOfOptionalHeader e000 ;constant
Characteristics 0201 ;executableon32-bit-machine
下面是optionalheader,起始于0x580x60slong: Magic 0b01 ;constant
MajorLinkerVersion 00 ;I'mversion0.0:-)
MinorLinkerVersion 00 ;
SizeOfCode 20000000;32sofcode
SizeOfInitializedData ????????;yettofindout
SizeOfUninitializedData 00000000;wedon'thaveaBSS
AddressOfEntryPo ????????;yettofindout
BaseOfCode ????????;yettofindout
BaseOfData ????????;yettofindout
ImageBase 00001000;1MB,chosenarbitrarily
SectionAlignment 20000000;32-s-alignment
FileAlignment 20000000;32-s-alignment
MajorOperatingVersion 0400 ;NT4.0
MinorOperatingVersion 0000 ;
MajorImageVersion 0000 ;version0.0
MinorImageVersion 0000 ;
MajorSubsystemVersion 0400 ;Win324.0
MinorSubsystemVersion 0000 ;
Win32VersionValue 00000000;unused?
SizeOfImage ????????;yettofindout
SizeOfHeaders ????????;yettofindout
CheckSum 00000000;notusedfornon-drivers
Subsystem 0300 ;Win32console
DllCharacteristics 0000 ;unused(notaDLL)
SizeOfStackReserve 00001000;1MBstack
SizeOfStackCommit 00100000;4KBtostartwith
SizeOfHeapReserve 00001000;1MBheap
SizeOfHeapCommit 00100000;4KBtostartwith
LoaderFlags 00000000;unknown
NumberOfRvaAndSizes 10000000;constant
计划2个节个是代码个是数据(包括数据常量和输入目录)没有重定位没有其他资源没有BSS段变量'written'填入化数据节对齐和文件对齐都是32字节现在建立数据目录开始于0xb80x80字节长只有引入目录被使用
Address Size
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_EXPORT(0)
???????? ???????? ;IMAGE_DIRECTORY_ENTRY_IMPORT(1)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_RESOURCE(2)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_EXCEPTION(3)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_SECURITY(4)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_BASERELOC(5)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_DEBUG(6)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_COPYRIGHT(7)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_GLOBALPTR(8)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_TLS(9)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG(10)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT(11)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_IAT(12)
00000000 00000000 ;13
00000000 00000000 ;14
00000000 00000000 ;15
下面是节头首先是代码节包括上述汇编32字节长开始于0x138长度x28: Name 2e636f6465000000 ;".code"
VirtualSize 00000000 ;unused
VirtualAddress ???????? ;yettofindout
SizeOfRawData 20000000 ;code
PoerToRawData ???????? ;yettofindout
PoerToRelocations00000000 ;unused
PoerToLinenumbers00000000 ;unused
NumberOfRelocations 0000 ;unused
NumberOfLinenumbers 0000 ;unused
Characteristics 20000060 ;code,executable,readable
第 2个节包括数据起始于0x160长度x28: Name 2e64617461000000 ;".data"
VirtualSize 00000000 ;unused
VirtualAddress ???????? ;yettofindout
SizeOfRawData ???????? ;yettofindout
PoerToRawData ???????? ;yettofindout
PoerToRelocations00000000 ;unused
PoerToLinenumbers00000000 ;unused
NumberOfRelocations 0000 ;unused
NumberOfLinenumbers 0000 ;unused
Characteristics 400000c0 ;initialized,readable,writeable
下个是0x188,由于节必须按照32字节对齐所有填0到0x1a0: 000000000000 ;padding
000000000000
000000000000
000000000000
现在第节代码节来到了开始于0x1a00x20字节长 6A00 ;push 0x00000000
68???????? ;push off_written
6A0D ;push 0x0000000d
68???????? ;push offhello_
6AF5 ;push 0xfffffff5
2EFF15???????? ;call dwordptrcs:__imp__GetStdHandle@4
50 ;push eax
2EFF15???????? ;call dwordptrcs:__imp__WriteConsoleA@20
C3 ;ret
由于前面节长度不需要填0数据节接着出现:起始于0x1c0:
68656C6C6F2C20776F726C640A ;"hello,world
"
000000 ;paddingtoalign_written//为什么要对齐??文件对齐而已
00000000 ;_written
现在剩下是输入目录了引入2个从"kernel32.dll",紧随2个变量首先对齐到32个字节文件对齐000000000000000000000000 ;padding
IMAGE_IMPORT_DESCRIPTOR从0x1e0开始:只有个DLL所以只有个元素
OriginalFirstThunk ???????? ;yettofindout
TimeDateStamp 00000000 ;unbound
ForwarderChain ffffffff ;noforwarders
Name ???????? ;yettofindout
FirstThunk ???????? ;yettofindout
我们需要结束输入目录用0填充0x1f4: OriginalFirstThunk 00000000 ;terminator
TimeDateStamp 00000000 ;
ForwarderChain 00000000 ;
Name 00000000 ;
FirstThunk 00000000 ;
现在剩下DLL名字和2个thunks,及thunk-data,名DLL名字从0x208开始: 6b65726e656c33322e646c6c00 ;"kernel32.dll"
000000 ;paddingto32-bit-boundary
originalfirstthunk2个成员,起始于0x218: AddressOfData ???????? ;RVAtofunctionname"WriteConsoleA"
AddressOfData ???????? ;RVAtofunctionname"GetStdHandle"
00000000 ;terminator
firstthunk含有同样列表起始于0x224:(__imp__WriteConsoleA@20,at0x224)
AddressOfData ???????? ;RVAtofunctionname"WriteConsoleA"
(__imp__GetStdHandle@4,at0x228)
AddressOfData ???????? ;RVAtofunctionname"GetStdHandle"
00000000 ;terminator
现在只剩下2个名在IMAGE_IMPORT_BY_NAME.从0x230. 0100 ;ordinal,neednotbecorrect
5772697465436f6e736f6c654100 ;"WriteConsoleA"
0200 ;ordinal,neednotbecorrect
47657453746448616e646c6500 ;"GetStdHandle"
下面填充到0x260: 00000000000000000000000000000000;padding
00
------------现在结束我们知道所有字节偏移量我们可以实施修补地址和尺寸了
DOS-header,startingat0x0:
00|4d5a0000000000000000000000000000
10|00000000000000000000000000000000
20|00000000000000000000000000000000
30|00000000000000000000000040000000
signature,startingat0x40:
50450000
file-header,startingat0x44:
Machine 4c01 ;i386
NumberOfSections 0200 ;codeanddata
TimeDateStamp 00000000;whocares?
PoerToSymbolTable 00000000;unused
NumberOfSymbols 00000000;unused
SizeOfOptionalHeader e000 ;constant
Characteristics 0201 ;executableon32-bit-machine
optionalheader,startingat0x58:
Magic 0b01 ;constant
MajorLinkerVersion 00 ;I'mversion0.0:-)
MinorLinkerVersion 00 ;
SizeOfCode 20000000;32sofcode
SizeOfInitializedData a0000000;datasectionsize
SizeOfUninitializedData 00000000;wedon'thaveaBSS
AddressOfEntryPo a0010000;beginningofcodesection
BaseOfCode a0010000;RVAtocodesection
BaseOfData c0010000;RVAtodatasection
ImageBase 00001000;1MB,chosenarbitrarily
SectionAlignment 20000000;32-s-alignment
FileAlignment 20000000;32-s-alignment
MajorOperatingVersion 0400 ;NT4.0
MinorOperatingVersion 0000 ;
MajorImageVersion 0000 ;version0.0
MinorImageVersion 0000 ;
MajorSubsystemVersion 0400 ;Win324.0
MinorSubsystemVersion 0000 ;
Win32VersionValue 00000000;unused?
SizeOfImage c0000000;sumofallsectionsizes//没有包含头尺寸跟前面所说矛盾了
SizeOfHeaders a0010000;offto1stsection
CheckSum 00000000;notusedfornon-drivers
Subsystem 0300 ;Win32console
DllCharacteristics 0000 ;unused(notaDLL)
SizeOfStackReserve 00001000;1MBstack
SizeOfStackCommit 00100000;4KBtostartwith
SizeOfHeapReserve 00001000;1MBheap
SizeOfHeapCommit 00100000;4KBtostartwith
LoaderFlags 00000000;unknown
NumberOfRvaAndSizes 10000000;constant
datadirectories,startingat0xb8:
Address Size
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_EXPORT(0)
e0010000 6f000000 ;IMAGE_DIRECTORY_ENTRY_IMPORT(1)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_RESOURCE(2)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_EXCEPTION(3)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_SECURITY(4)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_BASERELOC(5)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_DEBUG(6)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_COPYRIGHT(7)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_GLOBALPTR(8)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_TLS(9)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG(10)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT(11)
00000000 00000000 ;IMAGE_DIRECTORY_ENTRY_IAT(12)
00000000 00000000 ;13
00000000 00000000 ;14
00000000 00000000 ;15
sectionheader(code),startingat0x138:
Name 2e636f6465000000 ;".code"
VirtualSize 00000000 ;unused
VirtualAddress a0010000 ;RVAtocodesection
SizeOfRawData 20000000 ;code
PoerToRawData a0010000 ;fileofftocodesection
PoerToRelocations00000000 ;unused
PoerToLinenumbers00000000 ;unused
NumberOfRelocations 0000 ;unused
NumberOfLinenumbers 0000 ;unused
Characteristics 20000060 ;code,executable,readable
sectionheader(data),startingat0x160:
Name 2e64617461000000 ;".data"
VirtualSize 00000000 ;unused
VirtualAddress c0010000 ;RVAtodatasection
SizeOfRawData a0000000 ;datasection
PoerToRawData c0010000 ;fileofftodatasection
PoerToRelocations00000000 ;unused
PoerToLinenumbers00000000 ;unused
NumberOfRelocations 0000 ;unused
NumberOfLinenumbers 0000 ;unused
Characteristics 400000c0 ;initialized,readable,writeable
(padding)
000000000000 ;padding
000000000000
000000000000
000000000000
codesection,startingat0x1a0:
6A00 ;push 0x00000000
68d0011000 ;push off_written
6A0D ;push 0x0000000d
68c0011000 ;push offhello_
6AF5 ;push 0xfffffff5
2EFF1528021000 ;call dwordptrcs:__imp__GetStdHandle@4
50 ;push eax
2EFF1524021000 ;call dwordptrcs:__imp__WriteConsoleA@20
C3 ;ret
datasection,beginningat0x1c0:
68656C6C6F2C20776F726C640A ;"hello,world
"
000000 ;paddingtoalign_written
00000000 ;_written
padding:
000000000000000000000000 ;padding
IMAGE_IMPORT_DESCRIPTOR,startingat0x1e0:
OriginalFirstThunk 18020000 ;RVAtoorig.1stthunk
TimeDateStamp 00000000 ;unbound
ForwarderChain ffffffff ;noforwarders
Name 08020000 ;RVAtoDLLname
FirstThunk 24020000 ;RVAto1stthunk
terminator(0x1f4):
OriginalFirstThunk 00000000 ;terminator
TimeDateStamp 00000000 ;
ForwarderChain 00000000 ;
Name 00000000 ;
FirstThunk 00000000 ;
TheDLLname,at0x208:
6b65726e656c33322e646c6c00 ;"kernel32.dll"
000000 ;paddingto32-bit-boundary
originalfirstthunk,startingat0x218:
AddressOfData 30020000 ;RVAtofunctionname"WriteConsoleA"
AddressOfData 40020000 ;RVAtofunctionname"GetStdHandle"
00000000 ;terminator
firstthunk,startingat0x224:
AddressOfData 30020000 ;RVAtofunctionname"WriteConsoleA"
AddressOfData 40020000 ;RVAtofunctionname"GetStdHandle"
00000000 ;terminator
IMAGE_IMPORT_BY_NAME,at0x230:
0100 ;ordinal,neednotbecorrect
5772697465436f6e736f6c654100 ;"WriteConsoleA"
IMAGE_IMPORT_BY_NAME,at0x240:
0200 ;ordinal,neednotbecorrect
47657453746448616e646c6500 ;"GetStdHandle"
(padding)
00000000000000000000000000000000;padding
00
Firstunused:0x260
--------------是32字节节对齐所以在windows98下该不工作可以在NT下工作要想在WIN98下工作必须插入许多0并修改RVA
最新评论