DLL_Injector.cpp

NotepadHook.cpp

 전에 올렸던것과 같지만 다시 후킹을 공부할겸 복습용으로 코드를 좀더 안정적으로 바꾸었다. 코딩 스타일을 통일하고 에러가 날만한 부분에 빠짐없이 리턴값을 확인하여 로깅한 것 뿐이지만 확실히 더 심리적으로 안정감이 느껴진다. 실무에서 로깅을 제대로 안해서 버그 잡기 힘들었던 것을 떠올리면 로깅은 제대로 해야한다는 생각이 들더라.

 두 번째 인자로 들어가는 DLL 파일 경로는 notepad.exe와 DLL파일이 같은 경로 내에 있거나 DLL파일이 환경변수 'PATH'에 등록되어있지 않다면 절대 경로를 써 주어야 정상 작동한다. 이유는 후킹 방식이 DLL 인젝션으로 notepad.exe 프로세스에 Thread를 만들어 돌리는 것이라 실행 경로도 notepad.exe 파일이 놓인 곳일 것이기 때문이라고 추론하고 있다. 혹시나 다른 이유라면 댓글로 알려주시길 바란다.


## 2019-06-17 추가 : 이 포스트의 소스코드는 WriteFile함수가 KernelBase.dll로 구현이 옮겨진 후의 환경에서만 동작합니다. (참고 : https://sanseolab.tistory.com/17)


DLL_Injector.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
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <Shlwapi.h>
 
DWORD findPID(LPCTSTR szProcessName);
BOOL injectDLL(DWORD dwPID, LPCTSTR szDLLName);
 
int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("[*] Usage : %s [Target] [DLL]\n", argv[0]);
        return 1;
    }
 
    if (!PathFileExists(argv[2])) {
        printf("[-] DLL Not Exists : %s\n", argv[2]);
        return 1;
    }
 
    DWORD pid = findPID(argv[1]);
    if (pid == 0xFFFFFFFF) {
        printf("[-] Process not found\n");
        return 1;
    }
    else {
        printf("[*] pid : %u\n", pid);
    }
    if (!injectDLL(pid, argv[2])) {
        printf("[-] Injection Failed\n");
        return 1;
    }
    else {
        printf("[*] Injection Successed\n");
    }
 
    return 0;
}
 
DWORD findPID(LPCTSTR szProcessName)
{
    DWORD dwPID = 0xFFFFFFFF;
    HANDLE hSnapshot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe;
 
    pe.dwSize = sizeof(PROCESSENTRY32);
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        printf("[*] CreateToolhelp32Snapshot Error\n");
        return 0xFFFFFFFF;
    }
 
    Process32First(hSnapshot, &pe);
    do {
        if (!_stricmp(szProcessName, pe.szExeFile)) {
            dwPID = pe.th32ProcessID;
            break;
        }
    } while (Process32Next(hSnapshot, &pe));
 
    CloseHandle(hSnapshot);
    return dwPID;
}
 
BOOL injectDLL(DWORD dwPID, LPCTSTR szDLLName)
{
    HANDLE hProcess, hThread;
    HMODULE hMod;
 
    LPVOID pRemoteBuf;
    DWORD dwBufSize = lstrlen(szDLLName) + 1;
    LPTHREAD_START_ROUTINE pThreadProc;
 
    // Get target process handle
    if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) == INVALID_HANDLE_VALUE) {
        printf("[-] OpenProcess Error\n");
        printf("[-] gle : 0x%x\n", GetLastError());
        return FALSE;
    }
 
    // Allocate memory to target process
    if ((pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE)) == INVALID_HANDLE_VALUE) {
        printf("[-] VirtualAllocEx Error\n");
        printf("[-] gle : 0x%x\n", GetLastError());
        return FALSE;
    }
    
    // Write DLL name to target process memory
    if (WriteProcessMemory(hProcess, pRemoteBuf, szDLLName, dwBufSize, NULL== FALSE) {
        printf("[-] WriteProcessMemory Error\n");
        printf("[-] gle : 0x%x\n", GetLastError());
        return FALSE;
    }
    
    // Get handle of "kernel32.dll"
    if ((hMod = GetModuleHandle("kernel32.dll")) == INVALID_HANDLE_VALUE) {
        printf("[-] GetModuleHandle Error\n");
        printf("[-] gle : 0x%x\n", GetLastError());
        return FALSE;
    }
 
    // Get address of "LoadLibraryA"
    if ((pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA")) == INVALID_HANDLE_VALUE) {
        printf("[-] GetProcAddress Error\n");
        printf("[-] gle : 0x%x\n", GetLastError());
        return FALSE;
    }
 
    // Create and run remote thread in target process
    if ((hThread = CreateRemoteThread(hProcess, NULL0, pThreadProc, pRemoteBuf, 0NULL)) == INVALID_HANDLE_VALUE) {
        printf("[-] CreateRemoteThread Error\n");
        printf("[-] gle : 0x%x\n", GetLastError());
        return FALSE;
    }
 
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return TRUE;
}
cs


NotepadHook.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
#include <stdio.h>
#include <Windows.h>
 
#pragma pack(1)
struct IAT_STRUCT
{
    SHORT Opcode;
    LPVOID lpTarget;
};
 
typedef BOOL WINAPI tWriteFile(
    _In_        HANDLE       hFile,
    _In_        LPCVOID      lpBuffer,
    _In_        DWORD        nNumberOfBytesToWrite,
    _Out_opt_   LPDWORD      lpNumberOfBytesWritten,
    _Inout_opt_ LPOVERLAPPED lpOverlapped
);
 
tWriteFile* prevFunction;
tWriteFile* newFunction;
 
BOOL WINAPI NewWriteFile(
    _In_        HANDLE       hFile,
    _In_        LPCVOID      lpBuffer,
    _In_        DWORD        nNumberOfBytesToWrite,
    _Out_opt_   LPDWORD      lpNumberOfBytesWritten,
    _Inout_opt_ LPOVERLAPPED lpOverlapped
)
{
    if (nNumberOfBytesToWrite > 0)
        MessageBoxA(NULL, (LPCSTR)lpBuffer, NULLNULL);
    return prevFunction(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
}
 
DWORD WINAPI tryHook()
{
    // Get address of target function
    LPVOID lpOrgFunc = NULL;
    if ((lpOrgFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile")) == NULL)
        return -1;
 
    // Backup old protect
    DWORD dwOldProtect;
    if (VirtualProtect(lpOrgFunc, 6, PAGE_EXECUTE_READWRITE, &dwOldProtect) == NULL)
        return -1;
 
    // Backup old function IAT
    IAT_STRUCT*  lpSavedFunc = (IAT_STRUCT*)VirtualAlloc(NULLsizeof(IAT_STRUCT), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    IAT_STRUCT   newFuncObj;
    memcpy_s(lpSavedFunc, 6, lpOrgFunc, 6);
    prevFunction = (tWriteFile*)lpSavedFunc;
 
    // Absolute Jump
    newFuncObj.Opcode = 0x25FF;
 
    // Set new functon to replace
    newFunction = &NewWriteFile;
    newFuncObj.lpTarget = &newFunction;
 
    // Replacing
    memcpy_s(lpOrgFunc, 6&newFuncObj, 6);
 
    // Rollback protection
    VirtualProtect(lpOrgFunc, 6, dwOldProtect, NULL);
    return 0;
}
 
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    HANDLE hThread;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        tryHook();
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
cs


블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요