VOID StartInject(
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId,
/
/
where image
is
mapped
IN PIMAGE_INFO ImageInfo
)
{
NTSTATUS ntStatus;
PIMAGE_IMPORT_DESCRIPTOR pImportNew;
HANDLE hProcessHandle
=
NULL;
ULONG nImportDllCount
=
0
;
SIZE_T size;
IMAGE_IMPORT_DESCRIPTOR Add_ImportDesc;
PULONG ulAddress;
ULONG oldCr0;
ULONG Func;
PIMAGE_IMPORT_BY_NAME ptmp;
IMAGE_THUNK_DATA
*
pOriginalThunkData;
IMAGE_THUNK_DATA
*
pFirstThunkData;
PIMAGE_BOUND_IMPORT_DESCRIPTOR pBoundImport;
PVOID lpBuffer
=
NULL;
PVOID lpDllName
=
NULL;
PVOID lpExportApi
=
NULL;
PVOID lpTemp
=
NULL;
PVOID lpTemp2
=
NULL;
do
{
PEPROCESS g_eprocess
=
IoGetCurrentProcess();
/
/
基地址
ULONG ulBaseImage
=
(ULONG)ImageInfo
-
>ImageBase;
/
/
进程基地址
PIMAGE_DOS_HEADER pDos
=
(PIMAGE_DOS_HEADER)ulBaseImage;
/
/
32
位进程的NT头 是PIMAGE_NT_HEADERS32
64
位的需要另外定义
PIMAGE_NT_HEADERS32 pHeader
=
(PIMAGE_NT_HEADERS32)(ulBaseImage
+
(ULONG)pDos
-
>e_lfanew);
IMAGE_OPTIONAL_HEADER32 opt
=
pHeader
-
>OptionalHeader;
if
(opt.Magic !
=
IMAGE_NT_OPTIONAL_HDR32_MAGIC)
{
WriteErrorLogFile(
"32位程序 PE可选头解析错误"
);
break
;
}
/
/
这里可能出问题
32
位程序和
64
位程序的可选PE头是不一样的
PIMAGE_IMPORT_DESCRIPTOR pImportDesc
=
(PIMAGE_IMPORT_DESCRIPTOR)(pHeader
-
>OptionalHeader.DataDirectory[
1
].VirtualAddress
+
ulBaseImage);
/
/
获取导入表的个数
nImportDllCount
=
opt.DataDirectory[
1
].Size
/
sizeof(IMAGE_IMPORT_DESCRIPTOR);
/
/
打开被注入进程的进程对象
ntStatus
=
ObOpenObjectByPointer(g_eprocess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS,
/
/
PROCESS_WRITECOPY
NULL, KernelMode, &hProcessHandle);
if
(!NT_SUCCESS(ntStatus))
{
WriteErrorLogFile(
"模块回调中 ObOpenObjectByPointer失败"
);
break
;
}
/
/
数据目录表中的导入表大小增加一个 IMAGE_IMPORT_DESCRIPTOR 结构
size
=
sizeof(IMAGE_IMPORT_DESCRIPTOR)
*
(nImportDllCount
+
1
);
/
/
重新分配导入表
ntStatus
=
ZwAllocateVirtualMemory(hProcessHandle, &lpBuffer,
0
, &size,
MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
if
(!NT_SUCCESS(ntStatus))
{
WriteErrorLogFile(
"模块回调中 重新分配导入表失败"
);
break
;
}
RtlZeroMemory(lpBuffer, sizeof(IMAGE_IMPORT_DESCRIPTOR)
*
(nImportDllCount
+
1
));
size
=
20
;
/
/
分配当前进程空间。
ntStatus
=
ZwAllocateVirtualMemory(hProcessHandle, &lpDllName,
0
, &size,
MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
if
(!NT_SUCCESS(ntStatus))
{
WriteErrorLogFile(
"模块回调中 分配当前进程空间失败"
);
break
;
}
RtlZeroMemory(lpDllName,
20
);
size
=
20
;
ntStatus
=
ZwAllocateVirtualMemory(hProcessHandle, &lpExportApi,
0
, &size,
MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
if
(!NT_SUCCESS(ntStatus))
{
WriteErrorLogFile(
"模块回调中 lpExportApi分配失败"
);
break
;
}
RtlZeroMemory(lpExportApi,
20
);
/
/
分配当前进程空间。
size
=
20
;
ntStatus
=
ZwAllocateVirtualMemory(hProcessHandle, &lpTemp,
0
, &size,
MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
if
(!NT_SUCCESS(ntStatus))
{
WriteErrorLogFile(
"模块回调中 lpExportApi分配失败"
);
break
;
}
RtlZeroMemory(lpTemp,
20
);
/
/
分配当前进程空间。
size
=
20
;
ntStatus
=
ZwAllocateVirtualMemory(hProcessHandle, &lpTemp2,
0
, &size,
MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
if
(!NT_SUCCESS(ntStatus))
{
break
;
}
RtlZeroMemory(lpTemp2,
20
);
pImportNew
=
lpBuffer;
/
/
拷贝原始数据
RtlCopyMemory(pImportNew, pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)
*
nImportDllCount);
/
/
构造自己的DLL IMAGE_IMPORT_DESCRIPTOR结构
pOriginalThunkData
=
(PIMAGE_THUNK_DATA)lpTemp;
pFirstThunkData
=
(PIMAGE_THUNK_DATA)lpTemp2;
ptmp
=
(PIMAGE_IMPORT_BY_NAME)lpExportApi;
ptmp
-
>Hint
=
0
;
/
/
至少要一个导出API Inj
RtlCopyMemory(ptmp
-
>Name,
"Inj"
, strlen(
"Inj"
));
pOriginalThunkData[
0
].u1.AddressOfData
=
(ULONG)ptmp
-
ulBaseImage;
pFirstThunkData[
0
].u1.AddressOfData
=
(ULONG)ptmp
-
ulBaseImage;
Add_ImportDesc.FirstThunk
=
(ULONG)pFirstThunkData
-
ulBaseImage;
Add_ImportDesc.TimeDateStamp
=
0
;
Add_ImportDesc.ForwarderChain
=
0
;
/
/
/
/
DLL名字的RVA
/
/
32
位DLL的名字
64
位另外设置
RtlCopyMemory(lpDllName,
"jbndakb17.dll"
, strlen(
"jbndakb17.dll"
));
Add_ImportDesc.Name
=
(ULONG)lpDllName
-
ulBaseImage;
Add_ImportDesc.Characteristics
=
(ULONG)pOriginalThunkData
-
ulBaseImage;
pImportNew
+
=
(nImportDllCount
-
1
);
RtlCopyMemory(pImportNew, &Add_ImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR));
pImportNew
+
=
1
;
RtlZeroMemory(pImportNew, sizeof(IMAGE_IMPORT_DESCRIPTOR));
/
/
关闭写保护
KIRQL oldIrql
=
WPOFF();
/
/
改导出表
pHeader
-
>OptionalHeader.DataDirectory[
1
].VirtualAddress
=
(ULONG)(pImportNew
-
nImportDllCount)
-
ulBaseImage;
pHeader
-
>OptionalHeader.DataDirectory[
1
].Size
+
=
sizeof(IMAGE_IMPORT_DESCRIPTOR);
pBoundImport
=
(PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG)opt.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress
+
ulBaseImage);
if
((ULONG)pBoundImport !
=
ulBaseImage)
{
/
/
取消绑定输入表里的所有东西
opt.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress
=
0
;
opt.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size
=
0
;
}
WPON(oldIrql);
DbgPrint(
"注入32位模块完成\n"
);
}
while
(FALSE);
if
(NULL !
=
hProcessHandle)
{
ZwClose(hProcessHandle);
hProcessHandle
=
NULL;
}
}