-
-
[原创]手工添加外部DLL输入表并调用添加函数
-
发表于:
2018-12-2 16:06
9214
-
许多时候需要在其他程序里面调用自己写的DLL,这就需要在其他程序里面添加自己DLL的输入表,要添加输入表我们就要先了解一下输入表的结构:
我们先看一下我们需要修改的程序的相关信息
-----------------------------------FileHead
Machine: 014C
NumberOfSections: 0002
TimeDateStamp: 00000000
PointerToSymbolTable: 00000000
NumberOfSymbols: 00000000
SizeOfOptionalHeader: 00E0
Characteristics: 030F
-----------------------------------OptionalHeader
Magic: 010B
MajorLinkerVersion: 06
MinorLinkerVersion: 00
SizeOfCode: 00000000
SizeOfInitializedData: 00000000
SizeOfUninitializedData: 00000000
AddressOfEntryPoint: 00001040
BaseOfCode: 00001000
BaseOfData: 00002000
//NT additional fields...
ImageBase: 00400000
SectionAlignment: 00001000
FileAlignment: 00000200
MajorOperatingSystemVersion: 0004
MinorOperatingSystemVersion: 0000
MajorImageVersion: 0000
MinorImageVersion: 0000
MajorSubsystemVersion: 0004
MinorSubsystemVersion: 0000
Win32VersionValue: 00000000
SizeOfImage: 00003000
SizeOfHeaders: 00000200
CheckSum: 00008217
Subsystem: 0002
DllCharacteristics: 0000
SizeOfStackReserve: 00100000
SizeOfStackCommit: 00001000
SizeOfHeapReserve: 00100000
SizeOfHeapCommit: 00001000
LoaderFlags: 00000000
NumberOfRvaAndSizes: 00000010
------------------------------------DataDirectory
No. VirtualAddress Size
0 00000000 00000000 EXPORT
1 00002040 00000050 IMPORT
2 00000000 00000000 RESOURCE
3 00000000 00000000 EXCEPTION
4 00000000 00000000 SECURITY
5 00000000 00000000 BASERELOC
6 00000000 00000000 DEBUG
7 00000000 00000000 ARCHITECTURE
8 00000000 00000000 GLOBALPTR
9 00000000 00000000 TLS
10 00000000 00000000 LOAD_CONFIG
11 00000000 00000000 BOUND_IMPORT
12 00002090 00000038 IAT
13 00000000 00000000 DELAY_IMPORT
14 00000000 00000000 COM_DESCRIPTOR
15 00000000 00000000 ...
--------------------------------Section
Name VirtualAddress VirtualSize PointerToRawData SizeOfRawData Characteristics
.text 00001000 00000368 00000200 00000400 60000020
.data 00002000 000001C0 00000600 00000200 C0000040
--------------------------------Import
ImpAddr: 00000640
OriginalFirstThunk: 000020C8
TimeDateStamp : 00000000
ForwarderChain : 00000000
FirstThunk : 00002090
●--user32.dll
pNameAddr: 00000690
0000 00000690 MessageBoxA
OriginalFirstThunk: 000020D0
TimeDateStamp : 00000000
ForwarderChain : 00000000
FirstThunk : 00002098
●--msvcrt.dll
pNameAddr: 00000698
0000 00000698 __set_app_type
0000 0000069C _controlfp
0000 000006A0 exit
0000 000006A4 strstr
0000 000006A8 _XcptFilter
0000 000006AC _exit
0000 000006B0 _except_handler3
OriginalFirstThunk: 000020F0
TimeDateStamp : 00000000
ForwarderChain : 00000000
FirstThunk : 000020B8
●--kernel32.dll
pNameAddr: 000006B8
0000 000006B8 GetCommandLineA
0000 000006BC GetStartupInfoA
0000 000006C0 GetModuleHandleA
从上面的数据可以看出,输入表的地址是:2040,不过这是虚拟地址,要转换成文件的地址,从节的信息可以看出,输入表在.data节,所以这样计算一下:2040-2000+600=640(其中2000是.data节的起始虚拟地址,600是.data节在文件中的起始地址),这就是输入表在文件中的地址了,我们看一下这个地址下的数据:
-----------------------------------FileHead
Machine: 014C
NumberOfSections: 0002
TimeDateStamp: 00000000
PointerToSymbolTable: 00000000
NumberOfSymbols: 00000000
SizeOfOptionalHeader: 00E0
Characteristics: 030F
-----------------------------------OptionalHeader
Magic: 010B
MajorLinkerVersion: 06
MinorLinkerVersion: 00
SizeOfCode: 00000000
SizeOfInitializedData: 00000000
SizeOfUninitializedData: 00000000
AddressOfEntryPoint: 00001040
BaseOfCode: 00001000
BaseOfData: 00002000
//NT additional fields...
ImageBase: 00400000
SectionAlignment: 00001000
FileAlignment: 00000200
MajorOperatingSystemVersion: 0004
MinorOperatingSystemVersion: 0000
MajorImageVersion: 0000
MinorImageVersion: 0000
MajorSubsystemVersion: 0004
MinorSubsystemVersion: 0000
Win32VersionValue: 00000000
SizeOfImage: 00003000
SizeOfHeaders: 00000200
CheckSum: 00008217
Subsystem: 0002
DllCharacteristics: 0000
SizeOfStackReserve: 00100000
SizeOfStackCommit: 00001000
SizeOfHeapReserve: 00100000
SizeOfHeapCommit: 00001000
LoaderFlags: 00000000
NumberOfRvaAndSizes: 00000010
------------------------------------DataDirectory
No. VirtualAddress Size
0 00000000 00000000 EXPORT
1 00002040 00000050 IMPORT
2 00000000 00000000 RESOURCE
3 00000000 00000000 EXCEPTION
4 00000000 00000000 SECURITY
5 00000000 00000000 BASERELOC
6 00000000 00000000 DEBUG
7 00000000 00000000 ARCHITECTURE
8 00000000 00000000 GLOBALPTR
9 00000000 00000000 TLS
10 00000000 00000000 LOAD_CONFIG
11 00000000 00000000 BOUND_IMPORT
12 00002090 00000038 IAT
13 00000000 00000000 DELAY_IMPORT
14 00000000 00000000 COM_DESCRIPTOR
15 00000000 00000000 ...
--------------------------------Section
Name VirtualAddress VirtualSize PointerToRawData SizeOfRawData Characteristics
.text 00001000 00000368 00000200 00000400 60000020
.data 00002000 000001C0 00000600 00000200 C0000040
--------------------------------Import
ImpAddr: 00000640
OriginalFirstThunk: 000020C8
TimeDateStamp : 00000000
ForwarderChain : 00000000
FirstThunk : 00002090
●--user32.dll
pNameAddr: 00000690
0000 00000690 MessageBoxA
OriginalFirstThunk: 000020D0
TimeDateStamp : 00000000
ForwarderChain : 00000000
FirstThunk : 00002098
●--msvcrt.dll
pNameAddr: 00000698
0000 00000698 __set_app_type
0000 0000069C _controlfp
0000 000006A0 exit
0000 000006A4 strstr
0000 000006A8 _XcptFilter
0000 000006AC _exit
0000 000006B0 _except_handler3
OriginalFirstThunk: 000020F0
TimeDateStamp : 00000000
ForwarderChain : 00000000
FirstThunk : 000020B8
●--kernel32.dll
pNameAddr: 000006B8
0000 000006B8 GetCommandLineA
0000 000006BC GetStartupInfoA
0000 000006C0 GetModuleHandleA
从上面的数据可以看出,输入表的地址是:2040,不过这是虚拟地址,要转换成文件的地址,从节的信息可以看出,输入表在.data节,所以这样计算一下:2040-2000+600=640(其中2000是.data节的起始虚拟地址,600是.data节在文件中的起始地址),这就是输入表在文件中的地址了,我们看一下这个地址下的数据:
现在的数据来看加一个输入函数是很困难的,因为要将数据整体下移才能挪出空间了,这样要改动的数据就太多了,不过来逆向思维一下,我采取了两个方法来获得空间,首先新增的
IMAGE_IMPORT_DESCRIPTOR结构不往后加,放到现有数据的前面,现在就是
IMAGE_THUNK_DATA32结构还没有空间,我采用的方法是,把
IMAGE_IMPORT_DESCRIPTOR结构中的
OriginalFirstThun清零,这样它指向的数据空间就是放出来了,我们用这部分空间来保存新的输入表,空间都有了,现在就来增加我们需要的输入表。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2018-12-3 09:14
被lrtlrt编辑
,原因: