C++ 嵌套汇编

langzi8818 2008-07-24 12:52:13
我自己写了个TSTDLG程序,就一对话框。然后再DLG类里面写了个成员函数
void CTextDlgDlg::Test()
{
MessageBox(m_strRes, "1234565");
}

这个函数调用了下,便于找函数地址
void CTextDlgDlg::OnButton1()
{
// TODO: Add your control notification handler code here
int n = TCYAdd();
m_strRes.Format("%d", n);
Test();
//UpdateData(FALSE);
}

然后我利用远程注入方式,让TSTDLG加载一个动态库。并且成功
动态库加载初始时,我想更具函数地址直接调用这个函数Test。Test的地址为00401570,通过OD找到。
00401541 8BF1 MOV ESI,ECX
00401543 E8 5A040000 CALL <JMP.&FunDll.#1>
00401548 50 PUSH EAX
00401549 8D46 60 LEA EAX,DWORD PTR DS:[ESI+60]
0040154C 68 20304000 PUSH TextDlg.00403020 ; ASCII "%d"
00401551 50 PUSH EAX
00401552 E8 5D020000 CALL <JMP.&MFC42.#2818>
00401557 83C4 0C ADD ESP,0C
0040155A 8BCE MOV ECX,ESI
0040155C E8 0F000000 CALL TextDlg.00401570
00401561 5E POP ESI ; TextDlg.004022F8
00401562 C3 RETN


然后我再DLL中调用如下
BOOL CHOOKDllApp::InitInstance()
{
AfxMessageBox("DLL Load Success");

int p = 00401570;
__asm
{
CALL p;
}

AfxMessageBox("Call End");
return CWinApp::InitInstance();
}

但是没有成功,执行完AfxMessageBox("DLL Load Success");后,没有执行AfxMessageBox("Call End");
请高人指点如何调用!
...全文
336 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
KernelDbg 2008-07-28
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 gzgzlxg 的回复:]
引用 1 楼 c_cfan 的回复:
int p = 00401570;
__asm
{
CALL p;
}

好象有点问题,汇编中的地址是HEX,你这个是DEC吧?

call是调用程序,不知道你是不是要调用p位置处的程序


int p = 00401570
改成
int p = 0x00401570
这样 call p是可以正确的调用0x00401570的;
编译器编译后的汇编代码是:
mov [local.p],00401570
call [local.p]
问题是这个调用入口的参数是什么?例如该调…
[/Quote]


他那个函数没参数,不需要参数入栈,所以也不需要平衡堆栈
有参数的话最后一个参数先入栈
cdecl调用需要调用者平衡堆栈,用add esp,n
thiscall和stdcall返回指令是ret n,已经做了平衡
pigHead_chen 2008-07-28
  • 打赏
  • 举报
回复
“CALL 0x00401570”是把EIP的内容入栈保存,然后把0x00401570复制到EIP,然后CPU从EIP的新区域读取执行。

我想问CALL 0x00401570会跳到函数那里执行吗?
能跳到函数
Test:
...
leave
ret
然后又返回吗?
pigHead_chen 2008-07-28
  • 打赏
  • 举报
回复

[Quote=引用 12 楼 cnzdgs 的回复:]
如果是注入的DLL,目标进程不会主动调用DLL的导出函数,所以也就没法通过参数来传递回调函数指针了。
你要调用的是一个类的非静态成员函数,需要用ECX来传递对象指针,你要先想办法得到对象指针才行。(当然,如果该函数中没有使用this指针,不传也没关系)
[/Quote]

12楼的应该没错
gzgzlxg 2008-07-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 c_cfan 的回复:]
int p = 00401570;
__asm
{
CALL p;
}

好象有点问题,汇编中的地址是HEX,你这个是DEC吧?

call是调用程序,不知道你是不是要调用p位置处的程序
[/Quote]

int p = 00401570
改成
int p = 0x00401570
这样 call p是可以正确的调用0x00401570的;
编译器编译后的汇编代码是:
mov [local.p],00401570
call [local.p]
问题是这个调用入口的参数是什么?例如该调用需要通过堆栈传递两个参数(根据不同的编译器,还会通过寄存器传递上面所说的类似this这样的东西),这两个参数是p1和p2,
_asm {
//是什么调用入栈的顺序需要弄清楚?
push p1
push p2
call p
//是什么调用,是否需要清理堆栈?
add esp,?
}
不传递参数,不平衡堆栈,光有入口地址,是不能完成调用的。

langzi8818 2008-07-28
  • 打赏
  • 举报
回复
是我地址搞错了。结贴
谢谢各位
alan001 2008-07-28
  • 打赏
  • 举报
回复
谢谢楼主发布分享

UP
KernelDbg 2008-07-27
  • 打赏
  • 举报
回复
大家都已经说得很清楚了

现在关键是看你要用哪个进程执行test代码

如果是注入者执行,就按大家说的方法就行

如果是被注入进程执行,可以用detour库,或者手动修改指令,或者用DEBUG API都可以
langzi8818 2008-07-26
  • 打赏
  • 举报
回复
回复怎么没了 ????????
langzi8818 2008-07-25
  • 打赏
  • 举报
回复
的确如楼上所说。换了十六进制还是不行。
楼上说的是DLL定义回调函数给调用它的程序赋值。

我的目的就是,希望把一个DLL注入到一个EXE程序后,根据我反汇编到的一个CALL,调用它。因为刚开始学习汇编不久,所以想试验下,结果还是不行。请大侠指点
cnzdgs 2008-07-25
  • 打赏
  • 举报
回复
如果是注入的DLL,目标进程不会主动调用DLL的导出函数,所以也就没法通过参数来传递回调函数指针了。
你要调用的是一个类的非静态成员函数,需要用ECX来传递对象指针,你要先想办法得到对象指针才行。(当然,如果该函数中没有使用this指针,不传也没关系)
langzi8818 2008-07-24
  • 打赏
  • 举报
回复
请大家在多多发言,积极讨论,让我从中学到新知识
langzi8818 2008-07-24
  • 打赏
  • 举报
回复
谢谢各位。我回去后试试。不行再找大家
KernelDbg 2008-07-24
  • 打赏
  • 举报
回复
CTextDlgDlg的地址应该为程序执行到下面指令时esi的值
0040155A 8BCE MOV ECX,ESI

当然这种情况只适用于CTextDlgDlg是全局对象

如果是堆中对象,esi每次值不一样,而且不一定已经创建

但是无论如何,调用test函数都没问题
因为TEST里面没访问任何成员变量,也就是THIS指针没用到
rageliu 2008-07-24
  • 打赏
  • 举报
回复
一般会是
pushad
mov eax , p;
call eax;
popad

可以在原始文件里调用该函数,OD看它是怎么压参,传递this的

你没有对象,怎么能调用成员函数,也就是你的esi的值是怎么来的?
KernelDbg 2008-07-24
  • 打赏
  • 举报
回复
CTextDlgDlg的地址应该为程序执行到下面指令时esi的值
0040155A 8BCE MOV ECX,ESI
KernelDbg 2008-07-24
  • 打赏
  • 举报
回复
mov ecx,CTextDlgDlg对象的地址
不过这里不需要传递this指针
所以
__asm
{
CALL p; // 类中的函数调用要传递this指针,VC编译器应该通过ecx寄存器传递
}
应该是可以的
langzi8818 2008-07-24
  • 打赏
  • 举报
回复
int p = OX00401570;
__asm
{
move ECX, ESI;
CALL p; // 类中的函数调用要传递this指针,VC编译器应该通过ecx寄存器传递
}

就可以了吗
KernelDbg 2008-07-24
  • 打赏
  • 举报
回复
大概看了看:
int p = 00401570; // 这里应该是0x00401570吧:)

还有
__asm
{
CALL p; // 类中的函数调用要传递this指针,VC编译器应该通过ecx寄存器传递
}


不过在这里不用传递this指针,因为TEST函数没用访问对象里的任何成员

//下面是编译器的调用
0040155A 8BCE MOV ECX,ESI // esi是this,把this给ecx通过寄存器传递进去
0040155C E8 0F000000 CALL TextDlg.00401570




相门三少 2008-07-24
  • 打赏
  • 举报
回复
int p = 00401570;
__asm
{
CALL p;
}

好象有点问题,汇编中的地址是HEX,你这个是DEC吧?

call是调用程序,不知道你是不是要调用p位置处的程序
cnzdgs 2008-07-24
  • 打赏
  • 举报
回复
你现在的代码中的问题不只是十六进制,还有隐藏着其它问题。
你的目的是什么?如果要在DLL中调用EXE中的函数,正常的做法应该是用typedef定义一个函数指针类型,给DLL的导出函数用该类型定义一个参数,调用DLL时以函数名称作为参数。

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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