-2018 - 10 - 6 ~(P3)-프로세스 메모리 읽고 쓰기


1. 프로세스 자기 자신의 base address(0x00400000)부터 10바이트만큼 읽어서 출력

2. TlHelp32.h 내부의 함수를 이용해 PID, base address를 얻는 함수 정의

3. ASLR 옵션이 적용된 프로세스의 base address + 0x108E부터 6바이트만큼 읽어서 출력

4. base address + 0x108E부터 2바이트를{ 0x00, 0xEB }로 쓰기

5. base address + 0x108E부터 6바이트만큼 읽어서 출력



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
#include<stdio.h>
#include<stdlib.h>
#include<wchar.h>
#include<Windows.h>
#include<tlhelp32.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
 
void GetBaseAddressByName(PROCESSENTRY32 *sub)
{
    unsigned char buf1[] = { 0x000xEB };
    unsigned char buf2[20= { 0 }, bs[10= { 0 };
    int errCode;
    SIZE_T readSize;
 
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, sub->th32ProcessID);
 
    if (NULL != hProcess)
    {
        HMODULE hMod;
        //HINSTANCE 핸들은 보통 실행되고 있는 Win32 프로그램의 메모리 상에 올라가 있는 시작 주소값을 갖고 있음
        DWORD cbNeeded;
 
        if (EnumProcessModulesEx(hProcess, &hMod, sizeof(hMod),&cbNeeded,LIST_MODULES_64BIT))
            //EnumProcessModulesEx : 지정된 필터 조건을 충족시키는 지정된 프로세스의 각 모듈에 대한 핸들을 검색
        {
            GetModuleBaseName(hProcess, hMod, sub->szExeFile,sizeof(sub->szExeFile) / sizeof(TCHAR));
            //GetModuleBaseName : 지정된 모듈의 기본 이름을 검색
            //GetModuleBaseName 함수는 주로 디버거 및 다른 프로세스에서 모듈 정보를 추출해야하는 유사한 응용 프로그램에서 사용하도록 설계됨
                wprintf(TEXT("Base address : 0x%p\n"), hMod);
 
                printf("값 바꾸기 전..\n");
                ReadProcessMemory(hProcess, hMod + 0x108E, buf2, 6&readSize);
                printf("%u byte read!\n", readSize);
                for (int i = 0; i < 6; i++) {
                    printf("%#02x ", buf2[i]);
                }
                printf("\n");
                memset(buf2, 0sizeof(buf2));
 
                printf("값 바꾼 후..\n");
                WriteProcessMemory(hProcess, (LPVOID)((int)hMod + 0x108E), buf1, 2&readSize);
                printf("WriteProcessMemory error code : %d\n", GetLastError());
 
                printf("%u byte write!\n", readSize);
                ReadProcessMemory(hProcess, (LPCVOID)((int)hMod + 0x108E), buf2, 6&readSize);
                printf("ReadProcessMemory error code : %d\n", GetLastError());
                printf("%u byte read!\n", readSize);
                for (int i = 0; i < 6; i++) {
                    printf("%#02x ", buf2[i]);
                }
                printf("\n");
                errCode = GetLastError();
                printf("errCode : %d\n", errCode);
        }
    }
 
    CloseHandle(hProcess);
}
 
int main() {
    HANDLE hProcessSnap;
    PROCESSENTRY32 processinform, sub;
    processinform.dwSize = sizeof(PROCESSENTRY32);
    sub.dwSize = sizeof(PROCESSENTRY32);
 
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        printf("CreateToolhelp32Snapshot error \n");
 
    if (!Process32First(hProcessSnap, &processinform)) {
        printf("Process32First error ! \n");
        CloseHandle(hProcessSnap);
        return 0;
    }
    printf("LIST> \n");
    printf("\t\t[Process name \t[PID]\t[개수]\t[부모프로세스ID] \n");
 
    do {
        wprintf(L"%25s %8d %8d %16d \n"//유니코드 출려과 아스키코드 출력은 다르므로 유니코드를 출력하는 wprintf를 사용해야함
            processinform.szExeFile, processinform.th32ProcessID, processinform.cntThreads, processinform.th32ParentProcessID);
    } while (Process32Next(hProcessSnap, &processinform));
 
 
    printf("프로세스 이름 입력 :");
    memset(&sub, 0sizeof(sub));
    wscanf(L"%[^\n]s"&sub.szExeFile);  //%[^\n]s : 개행이 오기전까지 입력받음
    CloseHandle(hProcessSnap);
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        printf("CreateToolhelp32Snapshot error \n");
 
    if (!Process32First(hProcessSnap, &processinform)) {
        printf("Process32First error ! \n");
        CloseHandle(hProcessSnap);
        return 0;
    }
    while (Process32Next(hProcessSnap, &processinform)) {
        if (!wcscmp(sub.szExeFile, processinform.szExeFile)) {
            sub.th32ProcessID = processinform.th32ProcessID;
            sub.cntThreads = processinform.cntThreads;
            sub.th32ParentProcessID = processinform.th32ParentProcessID;
            printf("\t\t[Process name] \t[PID]\t[개수]\t[부모프로세스 ID] \n");
            wprintf(L"%25s %8d %8d %16d \n"//유니코드 출려과 아스키코드 출력은 다르므로 유니코드를 출력하는 wprintf를 사용해야함
                sub.szExeFile, sub.th32ProcessID, sub.cntThreads, sub.th32ParentProcessID);
            GetBaseAddressByName(&sub);
        }
    }
    CloseHandle(hProcessSnap);
 
    return 0;
}
cs


ASLR가 걸려있는 프로그램은 계속 변하는 베이스 어드레스를 찾기위해 조금 다른 함수가 쓰였다...

코드에서 확인><

'@안티치트' 카테고리의 다른 글

실제 프로그램에 적용해보기(메모리 읽고 쓰기)  (0) 2018.11.05
다른 프로세스의 메모리 읽기  (0) 2018.10.05
프로세스 메모리 읽어오기  (0) 2018.10.05
START!  (0) 2018.10.05

+ Recent posts