mirror of
https://github.com/gmh5225/awesome-game-security
synced 2026-06-21 13:56:22 +00:00
archive: add 5 repo prompt(s) [skip ci]
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,637 @@
|
||||
Project Path: arc_revsic_AntiDebugging_j3_wvy41
|
||||
|
||||
Source Tree:
|
||||
|
||||
```txt
|
||||
arc_revsic_AntiDebugging_j3_wvy41
|
||||
├── LICENSE
|
||||
├── README.md
|
||||
└── Sources
|
||||
├── AntiAntiAttach.cpp
|
||||
├── AntiAttach.cpp
|
||||
├── DR_Register_Resetter.cpp
|
||||
├── TextSectionHasher.cpp
|
||||
└── VEH_Checker.cpp
|
||||
|
||||
```
|
||||
|
||||
`LICENSE`:
|
||||
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 YoungJoong Kim
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
```
|
||||
|
||||
`README.md`:
|
||||
|
||||
```md
|
||||
# Anti Debugging
|
||||
|
||||
Anti debugging techniques written in C++.
|
||||
|
||||
- Anti Attach, Anti Anti Attach : [AntiAttach.cpp](Sources/AntiAttach.cpp), [AntiAntiAttaching.cpp](Sources/AntiAntiAttach.cpp)
|
||||
- Text Section Hashing : [TextSectionHasher.cpp](Sources/TextSectionHasher.cpp)
|
||||
- VEH Checker, DR Register Resetter : [VEH_Checker.cpp](Sources/VEH_Checker.cpp), [DR_Register_Resetter.cpp](Sources/DR_Register_Resetter.cpp)
|
||||
|
||||
## Anti Attach, Anti Anti Attach
|
||||
|
||||
Debugger attach process with `DebugActiveProcess` api.
|
||||
|
||||
```cpp
|
||||
DebugActiveProcess(pid);
|
||||
|
||||
DEBUG_EVENT dbgEvent;
|
||||
BOOL dbgContinue = True;
|
||||
|
||||
while (dbgContinue) {
|
||||
if (FALSE == WaitForDebugEvent(&dbgEvent, 100)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
It creates a thread in debuggee, then it calls `DbgUiRemoteBreakin()` to debug process.
|
||||
|
||||
```cpp
|
||||
//AntiAttach
|
||||
__declspec(naked) void AntiAttach() {
|
||||
__asm {
|
||||
jmp ExitProcess
|
||||
}
|
||||
}
|
||||
|
||||
//main
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
|
||||
FARPROC func_DbgUiRemoteBreakin = GetProcAddress(hMod, "DbgUiRemoteBreakin");
|
||||
|
||||
WriteProcessMemory(hProcess, func_DbgUiRemoteBreakin, AntiAttach, 6, NULL);
|
||||
```
|
||||
|
||||
Anti-Attacher hooks `DbgUiRemoteBreakin` and redirects it to `ExitProcess`. AntiAnti-Attacher releases the hooked function.
|
||||
|
||||
## Text Section Hashing
|
||||
|
||||
Debugger sets a software breakpoint by overwriting the `int 3` instruction.
|
||||
|
||||
It hashes text section and periodically checks that the text section has been changed.
|
||||
|
||||
```cpp
|
||||
while (1) {
|
||||
Sleep(1000);
|
||||
|
||||
DWORD64 dwCurrentHash = HashSection(lpVirtualAddress, dwSizeOfRawData);
|
||||
if (dwRealHash != dwCurrentHash) {
|
||||
MessageBoxW(NULL, L"DebugAttached", L"WARN", MB_OK);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bTerminateThread) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## VEH Checker, DR Register Resetter
|
||||
|
||||
VEH Debugger use Vectored Exception Handler.
|
||||
|
||||
It checks the fourth bit(`ProcessUsingVEH`) of the PEB's `CrossProcessFlags(+0x50)`. If `ProcessUsingVEH` bit is set, then VEH is being used.
|
||||
|
||||
```cpp
|
||||
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &ReturnLength);
|
||||
PPEB pPEB = (PPEB)pbi.PebBaseAddress;
|
||||
|
||||
SIZE_T Written;
|
||||
DWORD64 CrossProcessFlags = -1;
|
||||
ReadProcessMemory(hProcess, (PBYTE)pPEB + 0x50, (LPVOID)&CrossProcessFlags, sizeof(DWORD64), &Written);
|
||||
|
||||
printf("[*] CrossProcessFlags : %p\n", CrossProcessFlags);
|
||||
if (CrossProcessFlags & 0x4) {
|
||||
printf("[*] veh set\n");
|
||||
}
|
||||
else {
|
||||
printf("[*] veh unset\n");
|
||||
}
|
||||
```
|
||||
|
||||
VEH Debugger usually uses Hardware breakpoint. Verify hardware bp is set
|
||||
|
||||
```cpp
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
|
||||
|
||||
CONTEXT ctx;
|
||||
memset(&ctx, 0, sizeof(CONTEXT));
|
||||
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||
|
||||
ctx.Dr0 = 0;
|
||||
ctx.Dr1 = 0;
|
||||
ctx.Dr2 = 0;
|
||||
ctx.Dr3 = 0;
|
||||
ctx.Dr7 &= (0xffffffffffffffff ^ (0x1 | 0x4 | 0x10 | 0x40));
|
||||
|
||||
SetThreadContext(hThread, &ctx);
|
||||
CloseHandle(hThread);
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
`Sources/AntiAntiAttach.cpp`:
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#define DbgBreakPoint_FUNC_SIZE 0x2
|
||||
#define DbgUiRemoteBreakin_FUNC_SIZE 0x54
|
||||
#define NtContinue_FUNC_SIZE 0x18
|
||||
|
||||
struct FUNC {
|
||||
char *name;
|
||||
FARPROC addr;
|
||||
SIZE_T size;
|
||||
};
|
||||
|
||||
FUNC funcList[] = {
|
||||
{ "DbgBreakPoint", 0, DbgBreakPoint_FUNC_SIZE },
|
||||
{ "DbgUiRemoteBreakin", 0, DbgUiRemoteBreakin_FUNC_SIZE },
|
||||
{ "NtContinue", 0, NtContinue_FUNC_SIZE }
|
||||
};
|
||||
|
||||
DWORD GetPidByProcessName(WCHAR *name) {
|
||||
PROCESSENTRY32W entry;
|
||||
memset(&entry, 0, sizeof(PROCESSENTRY32W));
|
||||
entry.dwSize = sizeof(PROCESSENTRY32W);
|
||||
|
||||
DWORD pid = -1;
|
||||
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Process32FirstW(hSnapShot, &entry)) {
|
||||
do {
|
||||
if (!wcscmp(name, entry.szExeFile)) {
|
||||
pid = entry.th32ProcessID;
|
||||
break;
|
||||
}
|
||||
} while (Process32Next(hSnapShot, &entry));
|
||||
}
|
||||
|
||||
CloseHandle(hSnapShot);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
bool GetModuleNameByPid(DWORD pid, WCHAR *names) {
|
||||
MODULEENTRY32W module;
|
||||
memset(&module, 0, sizeof(MODULEENTRY32W));
|
||||
module.dwSize = sizeof(MODULEENTRY32W);
|
||||
|
||||
bool result = false;
|
||||
|
||||
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
|
||||
if (Module32FirstW(hSnapShot, &module)) {
|
||||
do {
|
||||
names += wsprintf(names, module.szModule);
|
||||
} while (Module32NextW(hSnapShot, &module));
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
CloseHandle(hSnapShot);
|
||||
return result;
|
||||
}
|
||||
|
||||
WCHAR* charToWChar(const char* text) {
|
||||
size_t size = strlen(text) + 1;
|
||||
WCHAR* wa = new WCHAR[size];
|
||||
mbstowcs(wa, text, size);
|
||||
return wa;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("USAGE : AntiAntiAttach.exe PROCESS_NAME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
WCHAR *pname = charToWChar(argv[1]);
|
||||
DWORD pid = GetPidByProcessName(pname);
|
||||
|
||||
if (pid == -1) {
|
||||
printf("[*] invalid process name\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
WCHAR modName[MAX_PATH] = { 0 };
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
|
||||
|
||||
HMODULE hMod = LoadLibraryW(L"ntdll.dll");
|
||||
for (int i = 0; i < _countof(funcList); ++i) {
|
||||
funcList[i].addr = GetProcAddress(hMod, funcList[i].name);
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
WCHAR names[2048];
|
||||
|
||||
if (GetModuleNameByPid(pid, names)) {
|
||||
if (wcsstr(names, L"ntdll") || wcsstr(names, L"NTDLL")) {
|
||||
for (int i = 0; i < _countof(funcList); ++i) {
|
||||
DWORD dwOldProtect;
|
||||
|
||||
VirtualProtectEx(hProcess, funcList[i].addr, funcList[i].size, PAGE_EXECUTE_READWRITE, &dwOldProtect);
|
||||
result = WriteProcessMemory(hProcess, funcList[i].addr, funcList[i].addr, funcList[i].size, NULL);
|
||||
VirtualProtectEx(hProcess, funcList[i].addr, funcList[i].size, dwOldProtect, NULL);
|
||||
|
||||
if (!result) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
printf("[*] patch success\n");
|
||||
}
|
||||
else {
|
||||
printf("[*] fail\n");
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`Sources/AntiAttach.cpp`:
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
|
||||
__declspec(naked) void AntiAttach() {
|
||||
__asm {
|
||||
jmp ExitProcess
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
|
||||
FARPROC func_DbgUiRemoteBreakin = GetProcAddress(hMod, "DbgUiRemoteBreakin");
|
||||
|
||||
WriteProcessMemory(hProcess, func_DbgUiRemoteBreakin, AntiAttach, 6, NULL);
|
||||
|
||||
int a, b;
|
||||
scanf("%d %d", &a, &b);
|
||||
|
||||
printf("result : %d\n", a + b);
|
||||
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`Sources/DR_Register_Resetter.cpp`:
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#define MAKEULONGLONG(ldw, hdw) ((ULONGLONG(hdw) << 32) | ((ldw) & 0xFFFFFFFF))
|
||||
DWORD GetMainThreadId(DWORD pid) {
|
||||
THREADENTRY32 th32;
|
||||
memset(&th32, 0, sizeof(THREADENTRY32));
|
||||
th32.dwSize = sizeof(THREADENTRY32);
|
||||
|
||||
DWORD dwMainThreadID = -1;
|
||||
|
||||
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);
|
||||
if (Thread32First(hSnapshot, &th32)) {
|
||||
DWORD64 ullMinCreateTime = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
do {
|
||||
if (th32.th32OwnerProcessID == pid) {
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
|
||||
|
||||
if (hThread) {
|
||||
FILETIME afTimes[4] = { 0 };
|
||||
if (GetThreadTimes(hThread, &afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3])) {
|
||||
ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime, afTimes[0].dwHighDateTime);
|
||||
if (ullTest && ullTest < ullMinCreateTime) {
|
||||
ullMinCreateTime = ullTest;
|
||||
dwMainThreadID = th32.th32ThreadID;
|
||||
}
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
} while (Thread32Next(hSnapshot, &th32));
|
||||
}
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
return dwMainThreadID;
|
||||
}
|
||||
|
||||
|
||||
DWORD GetPidByProcessName(WCHAR* name) {
|
||||
PROCESSENTRY32W entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.dwSize = sizeof(PROCESSENTRY32W);
|
||||
|
||||
DWORD pid = -1;
|
||||
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Process32FirstW(hSnapShot, &entry)) {
|
||||
do {
|
||||
if (!wcscmp(name, entry.szExeFile)) {
|
||||
pid = entry.th32ProcessID;
|
||||
break;
|
||||
}
|
||||
} while (Process32NextW(hSnapShot, &entry));
|
||||
}
|
||||
|
||||
CloseHandle(hSnapShot);
|
||||
return pid;
|
||||
}
|
||||
|
||||
int wmain(int argc, WCHAR *argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("USAGE : exec PROCESSNAME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD pid = GetPidByProcessName(argv[1]);
|
||||
DWORD tid = GetMainThreadId(pid);
|
||||
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
|
||||
|
||||
CONTEXT ctx;
|
||||
memset(&ctx, 0, sizeof(CONTEXT));
|
||||
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||
|
||||
ctx.Dr0 = 0;
|
||||
ctx.Dr1 = 0;
|
||||
ctx.Dr2 = 0;
|
||||
ctx.Dr3 = 0;
|
||||
ctx.Dr7 &= (0xffffffffffffffff ^ (0x1 | 0x4 | 0x10 | 0x40));
|
||||
|
||||
SetThreadContext(hThread, &ctx);
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`Sources/TextSectionHasher.cpp`:
|
||||
|
||||
```cpp
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
typedef struct {
|
||||
LPVOID lpVirtualAddress;
|
||||
DWORD dwSizeOfRawData;
|
||||
} SECTIONINFO, *PSECTIONINFO;
|
||||
|
||||
typedef struct {
|
||||
DWORD64 dwRealHash;
|
||||
SECTIONINFO SectionInfo;
|
||||
} HASHSET, *PHASHSET;
|
||||
|
||||
int GetAllModule(std::vector<LPVOID>& modules) {
|
||||
MODULEENTRY32W mEntry;
|
||||
memset(&mEntry, 0, sizeof(mEntry));
|
||||
mEntry.dwSize = sizeof(MODULEENTRY32);
|
||||
|
||||
DWORD curPid = GetCurrentProcessId();
|
||||
|
||||
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, NULL);
|
||||
if (Module32FirstW(hSnapshot, &mEntry)) {
|
||||
do {
|
||||
modules.emplace_back(mEntry.modBaseAddr);
|
||||
} while (Module32NextW(hSnapshot, &mEntry));
|
||||
}
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
|
||||
if (modules.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetTextSectionInfo(LPVOID lpModBaseAddr, PSECTIONINFO info) {
|
||||
PIMAGE_NT_HEADERS pNtHdr = ImageNtHeader(lpModBaseAddr);
|
||||
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHdr + 1);
|
||||
|
||||
LPVOID lpTextAddr = NULL;
|
||||
DWORD dwSizeOfRawData = NULL;
|
||||
|
||||
for (int i = 0; i < pNtHdr->FileHeader.NumberOfSections; ++i) {
|
||||
char *name = (char *)pSectionHeader->Name;
|
||||
|
||||
if (!strcmp(name, ".text")) {
|
||||
info->lpVirtualAddress = (LPVOID)((DWORD64)lpModBaseAddr + pSectionHeader->VirtualAddress);
|
||||
info->dwSizeOfRawData = pSectionHeader->SizeOfRawData;
|
||||
break;
|
||||
}
|
||||
|
||||
++pSectionHeader;
|
||||
}
|
||||
|
||||
if (info->dwSizeOfRawData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD64 HashSection(LPVOID lpSectionAddress, DWORD dwSizeOfRawData) {
|
||||
DWORD64 hash = 0;
|
||||
BYTE *str = (BYTE *)lpSectionAddress;
|
||||
for (int i = 0; i < dwSizeOfRawData; ++i, ++str) {
|
||||
if (*str) {
|
||||
hash = *str + (hash << 6) + (hash << 16) - hash;
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool bTerminateThread = false;
|
||||
|
||||
void CheckTextHash(PHASHSET pHashSet) {
|
||||
DWORD64 dwRealHash = pHashSet->dwRealHash;
|
||||
DWORD dwSizeOfRawData = pHashSet->SectionInfo.dwSizeOfRawData;
|
||||
LPVOID lpVirtualAddress = pHashSet->SectionInfo.lpVirtualAddress;
|
||||
|
||||
while (1) {
|
||||
Sleep(1000);
|
||||
|
||||
DWORD64 dwCurrentHash = HashSection(lpVirtualAddress, dwSizeOfRawData);
|
||||
if (dwRealHash != dwCurrentHash) {
|
||||
MessageBoxW(NULL, L"DebugAttached", L"WARN", MB_OK);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bTerminateThread) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ExitThreads(std::vector<std::thread>& threads) {
|
||||
bTerminateThread = true;
|
||||
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<LPVOID> modules;
|
||||
GetAllModule(modules);
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
threads.reserve(modules.size());
|
||||
|
||||
std::vector<HASHSET> hashes;
|
||||
hashes.reserve(modules.size());
|
||||
|
||||
for (auto& module : modules) {
|
||||
SECTIONINFO info;
|
||||
GetTextSectionInfo(module, &info);
|
||||
|
||||
DWORD64 dwRealHash = HashSection(info.lpVirtualAddress, info.dwSizeOfRawData);
|
||||
hashes.emplace_back(HASHSET { dwRealHash, info });
|
||||
threads.emplace_back(std::thread(CheckTextHash, &hashes.back()));
|
||||
}
|
||||
|
||||
int num1, num2;
|
||||
printf("[*] num1 num2 : ");
|
||||
scanf("%d %d", &num1, &num2);
|
||||
|
||||
printf("[*] result : %d\n\n", num1 + num2);
|
||||
|
||||
printf("[*] wait for terminating thread..\n");
|
||||
ExitThreads(threads);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`Sources/VEH_Checker.cpp`:
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <winternl.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
typedef NTSTATUS(WINAPI * fnNtQueryInformationProcess) (
|
||||
HANDLE ProcessHandle,
|
||||
PROCESSINFOCLASS ProcessInformationCLass,
|
||||
PVOID ProcessInformation,
|
||||
ULONG ProcessInformationLength,
|
||||
PULONG ReturnLength
|
||||
);
|
||||
|
||||
fnNtQueryInformationProcess GetNtQueryInformationProcess() {
|
||||
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
|
||||
if (hNtdll == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FARPROC func = GetProcAddress(hNtdll, "NtQueryInformationProcess");
|
||||
fnNtQueryInformationProcess query_func = (fnNtQueryInformationProcess)func;
|
||||
|
||||
return query_func;
|
||||
}
|
||||
|
||||
DWORD GetPidByProcessName(WCHAR *name) {
|
||||
PROCESSENTRY32W entry;
|
||||
memset(&entry, 0, sizeof(PROCESSENTRY32W));
|
||||
entry.dwSize = sizeof(PROCESSENTRY32W);
|
||||
|
||||
DWORD pid = -1;
|
||||
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Process32FirstW(hSnapShot, &entry)) {
|
||||
do {
|
||||
if (!wcscmp(name, entry.szExeFile)) {
|
||||
pid = entry.th32ProcessID;
|
||||
break;
|
||||
}
|
||||
} while (Process32Next(hSnapShot, &entry));
|
||||
}
|
||||
|
||||
CloseHandle(hSnapShot);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
int wmain(int argc, WCHAR *argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("[*] USAGE : exec PROCESSNAME");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD pid = GetPidByProcessName(argv[1]);
|
||||
fnNtQueryInformationProcess NtQueryInformationProcess = GetNtQueryInformationProcess();
|
||||
|
||||
ULONG ReturnLength;
|
||||
PROCESS_BASIC_INFORMATION pbi;
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
||||
|
||||
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &ReturnLength);
|
||||
PPEB pPEB = (PPEB)pbi.PebBaseAddress;
|
||||
|
||||
SIZE_T Written;
|
||||
DWORD64 CrossProcessFlags = -1;
|
||||
ReadProcessMemory(hProcess, (PBYTE)pPEB + 0x50, (LPVOID)&CrossProcessFlags, sizeof(DWORD64), &Written);
|
||||
|
||||
printf("[*] CrossProcessFlags : %p\n", CrossProcessFlags);
|
||||
if (CrossProcessFlags & 0x4) {
|
||||
printf("[*] veh set\n");
|
||||
}
|
||||
else {
|
||||
printf("[*] veh unset\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
+30586
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user