0x00 代码
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter)
{
int i = 0;
while (1) i++;
i--;
printf("ThreadProc end : %d\n",i);
return 0;
}
int _tmain(int agrc, TCHAR** argv)
{
int offset = 0;
BYTE* assm = NULL;
CONTEXT context = { 0 };
DWORD retValue = 0;
printf("%p %p\n", ThreadProc, *((VOID**)ThreadProc));
HANDLE thread = CreateThread(0, 0, ThreadProc, 0, 0, 0);
if (thread != NULL)
{
Sleep(100);
printf("CreateThread success\n");
retValue = SuspendThread(thread);
//suspend thread
if (retValue != -1)
{
printf("SuspendThread success%x\n", GetLastError());
//set context flag
context.ContextFlags = CONTEXT_CONTROL;
//get thread context
if (GetThreadContext(thread,&context))
{
printf("GetThreadContext success\n");
assm = (BYTE*) context.Rip;
for (DWORD64 i = 1; i < 100; i++)
{
SHORT a = *((SHORT*)(assm + i));
if (a == (SHORT)0xC8FF)
{
printf("find 0xFFC8 -> i-- \n");
context.Rip += i;
break;
}
}
//set thread context
if (SetThreadContext(thread, &context))
{
printf("SetThreadContext success\n");
}
}
retValue = ResumeThread(thread);
if (retValue != -1)
{
printf("ResumeThread success %x\n",GetLastError());
}
else
{
printf("ResumeThread failed\n");
}
}
Sleep(3000);
printf("Thread end\n");
CloseHandle(thread);
}
return 0;
}
0x01 注意事项
1 GetCurrentThread函数获取的是伪句柄,不能唯一的标识线程.通过GetCurrentThreadId获取线程ID来标识线程
2 同一个进程,不同线程的数据可以互相访问,该进程所有线程共享进程的虚拟空间.
3 通过CreateThread创建的线程,其函数地址随机
4 PC为小端存储,格式:高位存放在高地址,低位存放在地址.
代码执行是从低地址到高地址的,因此搜索代码时,要注意数据的高低位.如 i—对应编码 FF C8
C8在高地址即高位,FF在低地址即低位 -> 0XC8FF