VC中怎么执行一段机器码?

Daven172 2014-12-04 12:51:13
我调试的时候查找到
mov eax, 1
对应的机器码是
B8 01 00 00 00

写了如下的代码来运行:

const char *code = "\xB8\x01\x00\x00\x00";//mov eax, 1
void main()
{
__asm
{
lea eax, code;
call eax;
}
}

调试运行时出错:
0x01188000 处有未经处理的异常(在 code.exe 中): 0xC0000005: 执行位置 0x01188000 时发生访问冲突。
这种做法是对的吗?如果不对应该怎么做?
(运行环境:Win8.1 + VS2013)
另一种写法:
((void(*)())code)();
也试过
...全文
342 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Daven172 2014-12-08
  • 打赏
  • 举报
回复
找到原因了!原来是VS设置的问题,在项目名上右击->属性->链接器->高级->数据执行保护(DEP),选择否即可。
Daven172 2014-12-05
  • 打赏
  • 举报
回复
是Win8的问题,我用XP这样可以执行成功
fuchouzhe 2014-12-05
  • 打赏
  • 举报
回复
这是不区分数据块与程序块的做法,一般都是汇编直接写子程序后再编译。早期防盗版以及病毒才这么搞
zara 2014-12-04
  • 打赏
  • 举报
回复
那很可能就是数据执行保护 DEP 的缘故了,尤其是你没有主动地关闭它,好像 Win8 上的关闭 DEP 麻烦不少。
可以参照http://bbs.pcbeta.com/forum.php?mod=viewthread&tid=389564 的 3 楼查看自己系统 DEP 的当前状态。
Daven172 2014-12-04
  • 打赏
  • 举报
回复
引用 10 楼 zara 的回复:
不会吧,我用 vc2008 在 xp/sp3 上运行是正常的;你什么运行环境,或许是数据运行保护启用了?
win8.1 + vs2013
zara 2014-12-04
  • 打赏
  • 举报
回复
不会吧,我用 vc2008 在 xp/sp3 上运行是正常的;你什么运行环境,或许是数据运行保护启用了?
Daven172 2014-12-04
  • 打赏
  • 举报
回复
总结一下,我的lea确实是用错了,但是改正之后依然不行:

const char *code = "\xB8\x01\x00\x00\x00\xc3";//mov eax, 1; ret;
void main()
{
	__asm
	{
		mov eax, code;
		call eax;
	}
}
其实调试的时候确实是能看到即将执行的语句就是 mov eax, 1 但是一执行就会崩溃: 0x011458A8 处有未经处理的异常(在 shellcode.exe 中): 0xC0000005: 执行位置 0x011458A8 时发生访问冲突。
Daven172 2014-12-04
  • 打赏
  • 举报
回复
引用 5 楼 zara 的回复:
你这样的定义,lea 得到的是那个数组地址的地址,所以需要再加上 mov eax, [eax] 指令,或者干脆定义为const char code[]=。当然了,最后的 ret(0xc3) 指令还是需要的。 这个问题,其实也简单,你调试跟踪下就知道了。

const char *code = "\xB8\x01\x00\x00\x00\xc3";//mov eax, 1; ret;
void main()
{
	__asm
	{
		lea eax, code;
		mov eax, [eax];
		call eax;
	}
}
还是会崩溃,出错跟一开始的类似
Daven172 2014-12-04
  • 打赏
  • 举报
回复
引用 6 楼 Henzox 的回复:
[quote=引用 3 楼 Daven172 的回复:] [quote=引用 2 楼 Henzox 的回复:]

const char *code = "\xB8\x01\x00\x00\x00";//mov eax, 1
void main()
{
    __asm
    {
        mov eax, code;
        call eax;
    }
}
这样可以保证你执行到 mov eax, 1 但之后就可能崩溃了,需要返回。
执行 mov eax, 1的时候就崩溃了,应该不关ret的事[/quote] 请注意我的代码和你代码的区别,用我的代码,肯定能执行到你想要的 mov eax, 1[/quote] 不好意思,之前没看清楚你的代码,你是把 lea eax, code 改成了 mov eax, code 我试过了,还是不行
Henzox 2014-12-04
  • 打赏
  • 举报
回复
引用 3 楼 Daven172 的回复:
[quote=引用 2 楼 Henzox 的回复:]

const char *code = "\xB8\x01\x00\x00\x00";//mov eax, 1
void main()
{
    __asm
    {
        mov eax, code;
        call eax;
    }
}
这样可以保证你执行到 mov eax, 1 但之后就可能崩溃了,需要返回。
执行 mov eax, 1的时候就崩溃了,应该不关ret的事[/quote] 请注意我的代码和你代码的区别,用我的代码,肯定能执行到你想要的 mov eax, 1
zara 2014-12-04
  • 打赏
  • 举报
回复
你这样的定义,lea 得到的是那个数组地址的地址,所以需要再加上 mov eax, [eax] 指令,或者干脆定义为const char code[]=。当然了,最后的 ret(0xc3) 指令还是需要的。
这个问题,其实也简单,你调试跟踪下就知道了。
Daven172 2014-12-04
  • 打赏
  • 举报
回复
引用 1 楼 zara 的回复:
既然是用 call 去运行的,最起码得在 mov 后加上 ret 指令吧
执行 mov eax, 1的时候就崩溃了,应该不关ret的事
Daven172 2014-12-04
  • 打赏
  • 举报
回复
引用 2 楼 Henzox 的回复:

const char *code = "\xB8\x01\x00\x00\x00";//mov eax, 1
void main()
{
    __asm
    {
        mov eax, code;
        call eax;
    }
}
这样可以保证你执行到 mov eax, 1 但之后就可能崩溃了,需要返回。
执行 mov eax, 1的时候就崩溃了,应该不关ret的事
Henzox 2014-12-04
  • 打赏
  • 举报
回复

const char *code = "\xB8\x01\x00\x00\x00";//mov eax, 1
void main()
{
    __asm
    {
        mov eax, code;
        call eax;
    }
}
这样可以保证你执行到 mov eax, 1 但之后就可能崩溃了,需要返回。
zara 2014-12-04
  • 打赏
  • 举报
回复
既然是用 call 去运行的,最起码得在 mov 后加上 ret 指令吧

21,458

社区成员

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

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