- 2018-03-17 ~ (P2) - 다른 프로세스의 메모리 읽기
1. 다른 프로세스(Cpp_AnotherProcess.exe)의 핸들 얻기
1-1 TlHelp32.h
1) CreateToolhelp32Snapshot(), Process32First(), Process32Next()로 pId 얻기
2) OpenProcess()로 핸들 얻기
※특정 프로세스의 핸들을 얻는 다른 방법 찾아보기
2. ReadProcessMemory()로 0x40108B부터 6바이트만큼 읽어서 버퍼에 저장
3. 버퍼 출력
프로그램의 기능은 이렇다
//1. 현재 돌아가는 프로그램의 모든 스냅샷 출력
//2. 메모리를 읽고싶은 프로그램 입력
//3. WriteProcessMemory()로 0x40108E부터 2바이트를 {0x00,0xEB}로 쓰기
//4. ReadProcessMemory()로 0x40108E부터 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 | #include<stdio.h> #include<stdlib.h> #include<wchar.h> #include<Windows.h> #include<tlhelp32.h> void Read(PROCESSENTRY32 *sub) { HANDLE openPro; SIZE_T readSize; int buf1[3] = { 0x00,0xEB }, buf2[20] = { 0 }; int errCode; openPro = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sub->th32ProcessID); printf("값 바꾸기 전..\n"); ReadProcessMemory(openPro, (LPCVOID)0x40108E, buf2, 6, &readSize); for (int i = 0; i < 6; i++) { printf("%#02x ", buf2[i]); } printf("\n"); memset(buf2, 0, sizeof(buf2)); printf("값 바꾼 후..\n"); WriteProcessMemory(openPro, (LPVOID)0x40108E, buf1, 2, &readSize); ReadProcessMemory(openPro, (LPCVOID)0x40108E, buf2, 6, &readSize); for (int i = 0; i < 6; i++) { printf("%#02x ", buf2[i]); } printf("\n"); errCode = GetLastError(); printf("errCode : %d\n", errCode); } 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, 0, sizeof(sub)); wscanf(L"%s",&sub.szExeFile); 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); Read(&sub); } } CloseHandle(hProcessSnap); return 0; } | cs |
CreateToolhelp32Snapshot()
지정된 프로세스뿐만 아니라 이러한 프로세스가 사용하는 힙, 모듈 및 스레드의 스냅 샷을 가져옵니다.
1 | HANDLE CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID ); |
DWORD th32ProcessID :스냅 샷에 포함될 프로세스의 프로세스 식별자. 이 매개 변수는 현재 프로세스를 나타내는 0 일 수 있음
추가의 내용이 많으니 링크를 !
https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
Process32First()
시스템 스냅 샷에서 발생한 첫 번째 프로세스에 대한 정보를 검색
1 | BOOL Process32First( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ); |
매개변수
HANDLE hSnapshot : CreateToolhelp32Snapshot() 함수에 대한 이전 호출에서 반환 된 스냅 샷 핸들입니다.
LPPROCESSENTRY32 lppe : processentry32 구조체에 대한 포인터. 실행 파일의 이름, 프로세스 식별자 및 상위 프로세스의 프로세스 ID와 같은 프로세스 정보를 포함합니다.( 구조체의 사이즈는 deSize로 해야함)
프로세스 목록의 첫 번째 항목이 버퍼에 복사 된 경우 TRUE를 반환하고 그렇지 않으면 FALSE를 반환
Process32Next()
시스템 스냅 샷에 기록 된 다음 프로세스에 대한 정보를 검색합니다.
1 | BOOL Process32Next( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ); | cs |
ReadProcessMemory()
지정된 프로세스에서 메모리 영역에서 데이터를 읽습니다. 읽을 전체 영역에 액세스하거나 작업이 실패합니다.
1 2 3 4 5 6 7 8 | BOOL WINAPI ReadProcessMemory( _In_ HANDLE hProcess, _In_ LPCVOID lpBaseAddress, _Out_ LPVOID lpBuffer, _In_ SIZE_T nSize, _Out_ SIZE_T *lpNumberOfBytesRead ); | cs |
매개변수
hProcess : 읽히는 메모리가 있는 프로세스에 대한 핸들입니다. 핸들은 프로세스에 대한 PROCESS_VM_READ 액세스 권한이 있어야 합니다.
lpBaseAddress : 읽을 지정된 프로세스의 기본 주소에 대한 포인터
IpBuffer :지정된 프로세스의 주소 공간으로부터 내용을 수신하는 버퍼에 대한 포인터
nSize : 지정된 프로세스에서 읽을 바이트 수
lpNumberOfBytesRead : 지정된 버퍼로 전송된 바이트 수를 수신하는 변수에 대한 포인터
링크 ! https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms680553(v=vs.85).aspx
WriteProcessMemory()
지정된 프로세스의 메모리 영역에 데이터를 기록합니다. 기록할 전체 영역에 액세스해야 합니다. 그렇지 않으면 작업이 실패합니다.
1 2 3 4 5 6 7 | BOOL WINAPI WriteProcessMemory( _In_ HANDLE hProcess, _In_ LPVOID lpBaseAddress, _In_ LPCVOID lpBuffer, _In_ SIZE_T nSize, _Out_ SIZE_T *lpNumberOfBytesWritten ); | cs |
ReadProcessMemory()와 거의 비슷... 링크를!
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms681674(v=vs.85).aspx
'@안티치트' 카테고리의 다른 글
실제 프로그램에 적용해보기(메모리 읽고 쓰기) (0) | 2018.11.05 |
---|---|
프로세스 메모리 읽고 쓰기(ASLR) (0) | 2018.10.05 |
프로세스 메모리 읽어오기 (0) | 2018.10.05 |
START! (0) | 2018.10.05 |