[C++] 纯文本查看 复制代码
// FixIAT.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <stdlib.h>
#include <vector>
#define SE_DEBUG_PRIVILEGE 20
using namespace std;
typedef DWORD(WINAPI *PRtlAdjustPrivilege) (
ULONG Privilege,
BOOLEAN Enable,
BOOLEAN CurrentThread,
PBOOLEAN Enabled);
DWORD pid;
vector<DWORD> stub_addr;
vector<DWORD> iat_addr;
HANDLE hp;
void AdjustPrivilege() {
BOOLEAN Enabled;
PRtlAdjustPrivilege RtlAdjustPrivilege = (PRtlAdjustPrivilege)GetProcAddress(LoadLibraryA((LPCSTR)"ntdll.dll"), "RtlAdjustPrivilege");
RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &Enabled);
}
bool getStubFunc() {
DWORD addr;
DWORD t;
for (DWORD i = 0x47D170; i <= 0x47D1D0; i += 4) {
ReadProcessMemory(hp, (LPCVOID)i, &addr, sizeof(DWORD), &t);
if (t != sizeof(DWORD)) {
printf("What the fuck stub addr?\r\n");
getchar();
return false;
}
stub_addr.push_back(addr);
iat_addr.push_back(i);
}
ReadProcessMemory(hp, (LPCVOID)0x47D1EC, &addr, sizeof(DWORD), &t);
stub_addr.push_back(addr);
iat_addr.push_back(0x47D1EC);
if (t != sizeof(DWORD)) {
printf("What the fuck stub addr?\r\n");
getchar();
return false;
}
ReadProcessMemory(hp, (LPCVOID)0x47D1E4, &addr, sizeof(DWORD), &t);
stub_addr.push_back(addr);
iat_addr.push_back(0x47D1E4);
if (t != sizeof(DWORD)) {
printf("What the fuck stub addr?\r\n");
getchar();
return false;
}
ReadProcessMemory(hp, (LPCVOID)0x47D310, &addr, sizeof(DWORD), &t);
stub_addr.push_back(addr);
iat_addr.push_back(0x47D310);
if (t != sizeof(DWORD)) {
printf("What the fuck stub addr?\r\n");
getchar();
return false;
}
/* ReadProcessMemory(hp, (LPCVOID)0x47D200, &addr, sizeof(DWORD), &t);
stub_addr.push_back(addr);
if (t != sizeof(DWORD)) {
getchar();
printf("What the fuck stub addr?\r\n");
return false;
}
ReadProcessMemory(hp, (LPCVOID)0x47D398, &addr, sizeof(DWORD), &t);
stub_addr.push_back(addr);
if (t != sizeof(DWORD)) {
getchar();
printf("What the fuck stub addr?\r\n");
return false;
}*/
return true;
}
bool getIAT() {
LPVOID addr;
DWORD tid;
DWORD t;
HANDLE ht;
CONTEXT ct;
DEBUG_EVENT dbg;
DWORD last_eip;
bool state;
unsigned char c3 = 0xCC;
char opcode;
for (unsigned int i = 0; i < stub_addr.size(); i++) {
addr = (LPVOID)stub_addr[i];
ht = CreateRemoteThread(hp, NULL, 0, (LPTHREAD_START_ROUTINE)addr, NULL, CREATE_SUSPENDED, &tid);
if (ht == INVALID_HANDLE_VALUE) {
printf("What the fuck CreateRemoteThread?\r\n");
return false;
}
/*ct.ContextFlags = CONTEXT_FULL;
GetThreadContext(ht, &ct);
last_eip = ct.Eip;
ct.EFlags &= 0x100; //set IF = 1
SetThreadContext(ht, &ct);*/
ReadProcessMemory(hp, addr, &opcode, 1, &t);
WriteProcessMemory(hp, addr, &c3, 1, &t);
ResumeThread(ht);
state = true;
while (state) {
WaitForDebugEvent(&dbg, INFINITE);
switch (dbg.dwDebugEventCode) {
case EXCEPTION_DEBUG_EVENT:
if (dbg.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP) {
ct.ContextFlags = CONTEXT_FULL;
GetThreadContext(ht, &ct);
ct.EFlags |= 0x100; //set IF = 1
if (abs((int)last_eip - (int)ct.Eip) >= 1000) {
WriteProcessMemory(hp, (LPVOID)iat_addr[i], &ct.Eip, sizeof(DWORD), &t);
if (t != 4) {
printf("Fail: %08X, %08X\r\n", iat_addr[i], ct.Eip);
}
else {
printf("Succeed: %08X, %08X\r\n", iat_addr[i], ct.Eip);
}
TerminateThread(ht, 0);
state = false;
}
else {
last_eip = ct.Eip;
SetThreadContext(ht, &ct);
}
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_CONTINUE);
}
else if (dbg.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
if (dbg.u.Exception.ExceptionRecord.ExceptionAddress == LPVOID((DWORD)addr)) {
WriteProcessMemory(hp, addr, &opcode, 1, &t);
ct.ContextFlags = CONTEXT_FULL;
GetThreadContext(ht, &ct);
ct.Eip--;
last_eip = ct.Eip;
ct.EFlags |= 0x100; //set IF = 1
SetThreadContext(ht, &ct);
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_CONTINUE);
}
else {
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
}
}
else {
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
}
break;
case EXIT_PROCESS_DEBUG_EVENT:
printf("Why does the fuck process has been terminated?\r\n");
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_CONTINUE);
return false;
break;
case CREATE_THREAD_DEBUG_EVENT:
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_CONTINUE);
break;
default:
ContinueDebugEvent(pid, dbg.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
}
}
CloseHandle(ht);
}
return true;
}
bool supAllThreads() {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 te = {0};
HANDLE ht;
if (h == INVALID_HANDLE_VALUE) {
return false;
}
te.dwSize = sizeof(te);
BOOL state = Thread32First(h, &te);
while (state) {
if (te.th32OwnerProcessID != pid) {
state = Thread32Next(h, &te);
continue;
}
ht = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
SuspendThread(ht);
state = Thread32Next(h, &te);
CloseHandle(ht);
}
CloseHandle(h);
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
AdjustPrivilege();
scanf("%d", &pid);
hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
supAllThreads();
DebugActiveProcess(pid);
if (hp == NULL) {
printf("What the fuck pid and uac?\r\n");
getchar();
return -1;
}
getStubFunc();
getIAT();
DebugActiveProcessStop(pid);
system("pause");
return 0;
}