基本概念
除了DLL动态注入技术外,还可以通过手工修改PE文件的方式来加载DLL,这种方式只要应用过一次之后,每当进程开始运行时便会自动加载指定的DLL。
整体思路如下:
1、查看IDT是否有充足的空间,若无则移动IDT至其他位置,若有则直接添加至列表末尾;
2、若无,修改OPTIONAL头IMPORT TABLE的RVA值并增大Size值,删除绑定导入表BOUND IMPORT Table,复制原IAT内容到目标地址并设置INT、NAME、IAT,最后到.rdata节区头修改IAT属性值添加可写属性。
编写测试程序和DLL文件
下面练习的目标是编写简单的文本查看程序SKI12Viewer.exe,直接修改SKI12Viewer.exe文件使其在运行时自动加载myhack3.dll文件。
首先编写SKI12Viewer.exe。
SKI12Viewer.cpp
//SKI12Viewer.cpp
#include "windows.h"
#include "stdio.h"
TCHAR szAppName[] = L"SKI12Viewer" ;
TCHAR szFile[MAX_PATH] = {0,};
TCHAR szMsg[2048] = {0,};
#define MAX_BUF_SIZE (32768)
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam){
static HWND hwndEdit ;
HFONT hFont;
switch(iMsg){
case WM_CREATE :
hwndEdit = CreateWindow(L"Edit", NULL,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
WS_BORDER | ES_LEFT | ES_MULTILINE |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0, 0, 0, 0,
hwnd,(HMENU) 1,
((LPCREATESTRUCT)lParam)->hInstance, NULL);
hFont=CreateFont(16,0,0,0,0,0,0,0,0,0,0,0,0,L"Courier New");
SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
DragAcceptFiles(hwnd, TRUE);
return 0;
case WM_DROPFILES :
if( DragQueryFile((HDROP)wParam, 0, szFile, MAX_PATH) ){
HANDLE hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( hFile == INVALID_HANDLE_VALUE ){
wsprintf(szMsg, L"[-]File(\"%s\") open error!!! [%d]\n", szFile, GetLastError());
MessageBox(hwndEdit, szMsg, szAppName, MB_OK);
return 0;
}
DWORD dwBytesRead = 0;
char *pBuf = new char[MAX_BUF_SIZE];
ZeroMemory(pBuf, MAX_BUF_SIZE);
ReadFile(hFile, pBuf, MAX_BUF_SIZE, &dwBytesRead, NULL);
SetWindowTextA(hwndEdit, pBuf);
wsprintf(szMsg, L"SKI12Viewer (%s)", szFile);
SetWindowText(hwnd, szMsg);
delete []pBuf;
CloseHandle(hFile);
}
return 0;
case WM_SETFOCUS :
SetFocus(hwndEdit);
return 0;
case WM_SIZE :
MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wndclass);
hwnd = CreateWindow(
szAppName, szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,