一、程序要求
编写一个程序:创建一个子进程(执行其他程序,比如ollydbg)和一个子线程,在子线程中获取kernel32.dll的文件路径和子线程id,并在消息框中显示出来。
二、编程构想
编这个程序就是为了熟悉windows的相关API,有了这个基础以后,就可以着手编windows应用程序了(带UI的哦),那么我们看看这个程序需要用到哪些API?主要是用到MessageBox、CreateProcess、CreateThread、WaitForSingleObject、GetModuleHandle、GetModuleFIleName、GetProcAddress等API。
过程说明:我创建了一个ollydbg子进程后就通过close()函数割断了父子进程的联系,所以这样创建出来的子进程独立于父进程,并不需要父进程显式关闭。然后在子线程中依次调用GetModuleHandle(获取kernel32.dll句柄)、GetModuleFIleName(获取dll文件路径)、GetProcAddress(获取GetCurrentThreadId函数地址)等API,最后一个MessageBox显示结果就万事大吉了。值得注意的是,GetProcAddress的返回值有坑,我就在这里摔了一跤。
三、程序代码
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
typedef DWORD(*FUNCTION);//你可以把它理解为对API函数声明的复制
DWORD WINAPI children(LPVOID);//子线程,my children
int main(){
printf("第一步:创建一个ollydbg进程\n");
if(MessageBox(NULL,"创建一个新的ollydbg进程?","第一步",MB_OKCANCEL)==1){
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
CreateProcess(NULL,"E:\\tools\\OllyDbg\\ollydbg\\吾爱破解.exe",NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi);
printf("创建完毕,Happy Crack!\n");
close(pi.hProcess);
close(pi.hThread);
}
printf("第二步:创建一个子线程显示kernel路径和线程id的MessageBox\n");
if(MessageBox(NULL,"创建一个子线程显示kernel路径和线程id的MessageBox?","第二步",MB_OKCANCEL)==1){
WaitForSingleObject(CreateThread(NULL,0,children,NULL,0,NULL),INFINITE);
printf("程序结束!\n");
}
return 0;
}
DWORD WINAPI children()
{
TCHAR fileName[260]={0},id[10]={0};
DWORD threadid;
FUNCTION getThreadId=NULL;
HMODULE dllhd=GetModuleHandle("Kernel32.dll");//获取dll文件句柄。
GetModuleFileName(dllhd,fileName,260);//获取文件路径
threadid=(FUNCTION)GetProcAddress(dllhd,"GetCurrentThreadId")();//看到这里的FUNCTION了吗?它把返回的GetCurrentThreadId函数地址给合格化了,故而这里就是在调用“GetCurrentThreadId()”
_ultoa(threadid,id,10);//把int型转换为字符串
lstrcat(fileName,";id=");//字符串拼接
lstrcat(fileName,id);
MessageBox(NULL,fileName,"result",MB_OK);
return 0;
}
四、结果截图