作坊模块写CALL的经验.docx

上传人:小飞机 文档编号:3273262 上传时间:2023-03-12 格式:DOCX 页数:6 大小:39.81KB
返回 下载 相关 举报
作坊模块写CALL的经验.docx_第1页
第1页 / 共6页
作坊模块写CALL的经验.docx_第2页
第2页 / 共6页
作坊模块写CALL的经验.docx_第3页
第3页 / 共6页
作坊模块写CALL的经验.docx_第4页
第4页 / 共6页
作坊模块写CALL的经验.docx_第5页
第5页 / 共6页
亲,该文档总共6页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《作坊模块写CALL的经验.docx》由会员分享,可在线阅读,更多相关《作坊模块写CALL的经验.docx(6页珍藏版)》请在三一办公上搜索。

1、作坊模块写CALL的经验用作坊模块写CALL的经验之谈 大家在使用模块写CALL时,对于参数方面很容易搞错了,这里我给大家简单讲解一下要注意的事项与经验. 正确的汇编代码是 mov eax,0xA3EE20 mov eax,eax mov ecx,eax+0x178 mov edx,ecx push 0x0 push 0x3 push 0x7 call edx+0x1d0 从上面的意思,我们大概可以看出此CALL所传递的参数,有三个是通过入栈的,两个是分别通过ECX与EDX的, 基于_fastcall调用约定的正是会涉及ECX与EDX两寄存器,一般其它寄存器很少会参与参数的传递作用 上述代码分

2、成两部份来看,一部份是针对寄存器的,一部份是入栈的. 第一部份 寄存器操作 第一二句代码的意思是 eax=0xA3EE20 是把内存0xA3EE20处的4字节值放进EAX寄存器里. 第三句 ECX=eax+0x178 就是把之前读来的值+0x178做为内存地址,再次读取4字节数据放在ECX里 第四句 edx=ecx 把ecx的值作为内存地址,再读取4字节放在EDX寄存器里. 理解了上述的汇编代码后再看看这位会员与编写的代码,前三句的内存_读整数型与三次的CPU寄存器赋值,是完全正确的. 若要把意思写得更接近那个汇编代码可以如此 内存_读整数型(进程句柄,10743328,CPU.EAX) 0x

3、A3EE20 内存_读整数型(进程句柄,CPU.EAX+376,CPU.ECX) 0x178 内存_读整数型(进程句柄,CPU.ECX,CPU.EDX) 内存_读整数型(进程句柄,CPU.EDX+464,CALL地址) 0x1D0 通过前三句,就完成了ECX与EDX的值的设置,第四句取出来了要CALL的地址.大家可能会想问,为什么我上面的读内存时地址与+偏移不是用 十六到十( ) 进行转换,而是直接填写数字?因为转换来转换去,是消耗CPU的,其实这些值我们可以用计算器转一下,在编写代码时填写十进制的值,同时为了方便记忆呢,在代码后把十六进制的值做为注释就行了.当然这样会给写代码带来些麻烦. 再

4、看第二部份的PUSH入栈参数问题. 我们可以看到此会员写的代码是照抄汇编代码的. push 0x0 参数1=0 push 0x3 参数2=3 push 0x7 参数3=7 明明照抄的结果,却CALL起来无效.问题呢就是出在这时在. 原因是汇编代码是从上往下一句一句运行,那三句PUSH是先0再3最后7压进了栈里 而正常的软件编程里对于参数是先把右边向左的参数依次入栈,就是先压参数3,再压参数2,最后是参数1.意思就是与汇编里的刚好反过来的顺序. 所以正确的写法应该是 push 0x0 参数1=7 push 0x3 参数2=3 push 0x7 参数3=0 或许大家对我的讲解不太理解,但要记住这个

5、决窍就行了, 从你看到的汇编里CALL的那个开始,往上看所有的PUSH,在最接近CALL这句的为参数1就是了.再上面的PUSH就是参数2,再就是参数3,如此推即是. 另外还有一个问题就是汇编里是三个PUSH,此会员定义的参数数组成员数却是4个,这里也是错误的,应该改成3个. 最终所有的代码应该是 内存_读整数型(进程句柄,10743328,CPU.EAX) 0xA3EE20 内存_读整数型(进程句柄,CPU.EAX+376,CPU.ECX) 0x178 内存_读整数型(进程句柄,CPU.ECX,CPU.EDX) 内存_读整数型(进程句柄,CPU.EDX+464,CALL地址) 0x1D0 重定

6、义数组(参数,假,3) 参数1=7 参数2=3 参数3=0 调用函数(进程句柄,CALL地址,参数,CPU) 或者也可以写成 内存_读整数型(进程句柄,10743328,CPU.EAX) 0xA3EE20 内存_读整数型(进程句柄,CPU.EAX+376,CPU.ECX) 0x178 内存_读整数型(进程句柄,CPU.ECX,CPU.EDX) 内存_读整数型(进程句柄,CPU.EDX+464,CALL地址) 0x1D0 调用函数(进程句柄,CALL地址,7,3,0,CPU) 在易语言里使用 7,3,0 大括号的话会自动生成数组方式的数据传入. 大家可能会发现这样一个问题,读内存很麻烦.若少量的

7、读一下还好,若要大量的,或更复杂的读写内存寄存器操作,真的有点烦.还不如用汇编模块写起来方便些. 你的想法是对的,模块中的 调用函数 与 CALL 这两个功能只是为了简化一些事情,但简化的同时难免会失去一些灵活性,比如有大量的MOV或其它的汇编指令操作时. 此时就该使用模块里的 调用机器码 功能了.其实 调用函数 与 CALL 都是建立在 调用机器码 功能上的. 假如大家用汇编模块来写,那每一句都要进行翻译转换,就会浪费CPU资源,若这类的操作太多太频繁,会使挂变得卡起来. 所以这里我推荐大家使用OD来写代码.用OD打开任何一个程序, 来到OD的反汇编代码窗口.然后把汇编代码照抄进去就行了.最

8、后复制出来机器码.用模块里的 调用机器码 执行即可. 在OD里写好汇编代码后,选择这一段,右键复制出汇编代码,粘在易源代码里,OD再右键二进制-二进制复制 出来机器码也粘在易源代码里作备注用. 然后就可以写代码调用机器码来执行这段复制来的二进制代码即可. 调用机器码 (进程句柄, 十六进制到字节集 (“B8 20 EE A3 00 8B 00 8B 88 78 01 00 00 8B 11 6A 00 6A 03 6A 07 FF 92 D0 01 00 00”) 当然每次都用十六进制到字节集进行转换也是件麻烦事,大家可以先转换好,再填入字节集机器码指令即可 调用机器码 (进程句柄, 184,

9、 32, 238, 163, 0, 139, 0, 139, 136, 120, 1, 0, 0, 139, 17, 106, 0, 106, 3, 106, 7, 255, 146, 208, 1, 0, 0 ) 使用机器码有什么需要注意的呢?第一要注意的是不需要写如下格式的 push ebp mov ebp, esp mov esp, ebp pop ebp retn 或者 pushad pushfd popfd popad 因为模块的调用机器码会自动追加上了这些指令,若你再加上就成了重复了,反而会引起问题来. 还有一个问题就是在调用机器码里不应该有直接寻址的指令操作.如 jmp 0x00

10、401000 call 0x00401000 对于这类的指令要改成间接寻址才行,可以修改成 mov eax,0x00401000 jmp eax 假如不想用寄存器进行间接寻址,可以改成如 mov esp-4,0x00401000 jmp esp-4 以上此种间接方式.原因是因为调用机器码时,机器码会在任何可能的内存处.自然不能进行直接寻址操作. 除以上问题外,调用机器码直接传入参数与寄存器的方式.那么如上面的代码,又可以进行简化一下,变成如下图 如上图,三个要PUSH入栈的参数不写在OD里,而是做为调用机器码的参数传入,同时对于EAX最先要读取的内存地址,也用 cpu.eax 来传入了. 这里

11、需要注意的是,在OD里不是写CALL,而是写成了JMP. 使用调用机器码在执行的汇编指令,是被自动包在了汇编子程序段里的.就是如下 push ebp mov ebp, esp 用户的汇编机器码指令 在这里用户可以使用 ebp+8 访问到传入的参数1,ebp+c就是参数二 mov esp, ebp pop ebp retn 所以传入的参数是处于汇编机器码段,如果想把这些参数传给CALL目标里去,就不能用CALL了,得改用JMP过去.若不想用JMP的话,还是用CALL的话,就得在CALL前再次入栈参数 OD里的代码应该是 mov eax, dword ptr eax mov ecx, dword

12、ptr eax+178 mov edx, dword ptr ecx push ebp+0x10 先入栈参数三 push ebp+0xc 再入栈参数二 push ebp+8 后入栈参数一 call dword ptr edx+1D0 由此可见,最接近CALL的那个PUSH是参数1, 最后提示一下,在 调用机器码 调用函数 CALL 等,包括 一些注入DLL的功能里 都有一个 绑定线程 的参数. 除此之外还会额外加入SEH结构化异常保护机制.这些都是作坊模块里所特有的. 一般的其它汇编模块都是简单的采用远线程来执行机器码指令.没有这些特性的. 这个绑定线程的意思就是让这个功能强制在此线程环境下执行.不然会以创建多线程来执行这些功能, 此参数一般用来绑游戏的主线程用.当然也可以不绑,对于CALL这一类若不绑能正常使用时则最好不要绑.不然试试绑定游戏主线程句柄, 当然对于注入DLL方面的功能还是强烈推荐绑主线程的方式

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号