远线程问题~~~~~~~~~~

all4u 2008-06-21 08:54:15
麻烦大家看下这个远线程程序,目的是在程序中启动一个notepad进程,然后将本程序的TestClass函数写到notepad进程中,并用createremotethread启动这个程序。为什执行时能显示最后的inject success,却不能显示TestClass里的消息框?而且,程序被关闭。谢谢啊~~~~~~~~
//---------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

DWORD WINAPI TestClass(LPVOID lpParameter)
{
MessageBox(0,"Hello...","INFO",0);
return 0;
}

//--------------------------------------------------------------------------------------------

BOOL EnableDebugPrivilege()
{
HANDLE hToken;
BOOL fOk=FALSE;
LUID luid;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
TOKEN_PRIVILEGES tp;
if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
MessageBox(0,"Can't lookup privilege value.\n","INFO",0);
//在这里使用GetLastError(),返回0
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid=luid;

if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
MessageBox(0,"Can't adjust privilege value.\n","INFO",0);
//在这里使用GetLastError(),返回997
fOk=true;
CloseHandle(hToken);
}
return fOk;
}
//---------------------------------------------------------------------------------------------
int main(int argc,char* argv[])
{
int i=0;
STARTUPINFO start;
PROCESS_INFORMATION info;
memset(&start,0,sizeof(start));
BOOL bRet=CreateProcess("c:\\windows\\system32\\notepad.exe",
NULL,NULL,NULL,FALSE,
NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|PROCESS_VM_WRITE,
NULL,NULL,&start,&info);
HANDLE hRemoteProcess;
void *pStart;
void *pParam;
int iReturnCode;
int cb=(int)EnableDebugPrivilege-(int)TestClass+8000;//写入内容的大小

if(!EnableDebugPrivilege())
MessageBox(0,"Can't adjust token.\n","INFO",0);
hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD| //允许远程创建线程
PROCESS_VM_OPERATION| //允许远程VM操作
PROCESS_VM_WRITE, //允许远程VM写
FALSE,
info.dwProcessId);
if(!hRemoteProcess)
MessageBox(0,"Can't open the process.\n","INFO",0);
//写入函数体
pStart = VirtualAllocEx( hRemoteProcess,NULL,cb,MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if(!pStart)
exit(0);
iReturnCode = WriteProcessMemory(hRemoteProcess,pStart,&TestClass,cb,NULL);
if(!iReturnCode)
exit(0);
//Write function params//写入函数参数
pParam = VirtualAllocEx( hRemoteProcess,NULL,sizeof(char),MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if(!pParam)
exit(0);
iReturnCode = WriteProcessMemory(hRemoteProcess, pParam, &i, sizeof(int), NULL);
if(!iReturnCode)
exit(0);
HANDLE hRemoteThread = CreateRemoteThread(
hRemoteProcess, NULL, 0,
(PTHREAD_START_ROUTINE)pStart,//写入函数体时分配的地址
pParam,//函数参数地址
0,
NULL);

if(!hRemoteThread)
exit(0);
WaitForSingleObject(hRemoteThread,INFINITE);
CloseHandle(hRemoteProcess);
MessageBox(0,"Inject success!\n","INFO",0);
return 0;
}
...全文
103 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
all4u 2008-06-29
  • 打赏
  • 举报
回复
谢谢各位了~~~
先结贴了。要是有代码,麻烦能贴下就好了。
jasonweil 2008-06-28
  • 打赏
  • 举报
回复
可以考虑使用远程线程插入dll的方式实现,
这里涉及到windows进程的内存管理方式问题。你写的函数TestClass编译后易代码段形式存在于你的进程中。
其它进程无法从自己的进程地址中调用你的函数。
GetProcAddress从kernel32里得到loadlibrarya/w的地址,因为每个进程中的kernel32.dll的加载地址
都一样,所以你传loadlibrarya/w的地址,进程就能找到函数入口。
详细的可以看看win核心编程
zhengq06 2008-06-28
  • 打赏
  • 举报
回复


据说回帖是一种美德...
pigsanddogs 2008-06-28
  • 打赏
  • 举报
回复
另外, LoadLibrary, GetProcAddress 这两个api本身就无法调用, 只能想办法通过其他渠道获取。

因为在不同进程中这两个地址是一样的, 可以让你的lpParameter指向一个结构体,
里面包含了这两个地址。 当然这个结构体要先copy到远程进程中去。
pigsanddogs 2008-06-28
  • 打赏
  • 举报
回复
1: typedef int (*pfMessageBox)(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
2: HMODULE hMod=LoadLibrary("user32.dll");
3: pfMessageBox PFM=(pfMessageBox)GetProcAddress(hMod,"MessageBox");
4: if(PFM!=NULL)
5: (*PFM)(0,"HELLO","HELLO",0);

简单说下这几句话的编译过程吧。
1: 类型定义不参与编译, 所以不出问题
2: "user32.dll" 是一个放到.rdata的东西, 也就是说, 这个内容实际上是在你的exe里面的
静态存储区, 而不是在你的函数里面, 你的函数只是用一个地址而已。 然后插到了远程
远程的exe的静态存储区的这个位置已没有这个内容了, 所以报错,
于是必须在stack中构造这个过程, 如下面这样写
char usr32_buf[] = {'u','s','e','r','3','2','.','d','l','l',0};
HMODULE hMod=LoadLibrary(usr32_buf);
3: 同2
4: 没问题
5: 同2

记得必须单独的一个字母一个字母写, 这样才是立即数构造. mov byte ptr[esi], 'u'
如果char usr32_buf[] = "user32.dll";
那么编译器根据串的长度,有可能会在栈中一个一个的构造, 也可能来一次简单的rep movsd.
内存泄漏 2008-06-27
  • 打赏
  • 举报
回复
晕..不能这样,因为在远程进程中找不到MessageBox这条API函数的入口地址..从而调用不成功..,
你必须在main中用GetProcAddress获得MessageBoxA函数的入口地址,然后也注入到远程线程才行..
李马 2008-06-27
  • 打赏
  • 举报
回复
这种事情还是直接用机器码来做吧,可以参考我这篇:
http://www.titilima.cn/?action=show&id=216
all4u 2008-06-24
  • 打赏
  • 举报
回复
沉了,UP一下~~~~~~
all4u 2008-06-22
  • 打赏
  • 举报
回复
症状好像是楼上说的那样,我吧TestClass清空后程序不再出错。但是,我改动成如下:
DWORD WINAPI TestClass(LPVOID lpParameter)
{
typedef int (*pfMessageBox)(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
HMODULE hMod=LoadLibrary("user32.dll");
pfMessageBox PFM=(pfMessageBox)GetProcAddress(hMod,"MessageBox");
if(PFM!=NULL)
(*PFM)(0,"HELLO","HELLO",0);
return 0;
}
仍然出错,是不是因为里面的LoadLibrary和GetProcAddress两个API调用?是不是要将这两个API作为参数传递给TestClass然后才能在TestClass里进行使用呢?麻烦具体说一下,谢谢了~~~~~~~~
vocanicy 2008-06-21
  • 打赏
  • 举报
回复
问题在于这里(红色部分)
DWORD WINAPI TestClass(LPVOID lpParameter)
{
MessageBox(0,"Hello...","INFO",0);
return 0;
}

插入远程线程中的程序块中不能直接调用API,必须使用LoadLibrary和GetProcAddress来重新定位API函数

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧