栈溢出笔记1.5 换一个汇编工具
来源:互联网 发布:淘宝下载器 编辑:程序博客网 时间:2024/04/27 21:50
前面的内容中我们使用VC++内联汇编,虽然很方便,但是无法定义字符串常量,导致我们需要把字符串的ASCII码找到,再一个一个压入栈中,比较繁琐,本节,我们换一个汇编工具——nasm,选择它是因为它可以跨平台使用。
有了这个汇编工具,我们就可以定义字符串常量了,例如:
/*****************************************************************************/DB “example_1”, 0x00DB “HelloWorld”, 0x00/*****************************************************************************/
这样方便是方便了,但是出现了新的问题,我们不可能写成这个样子:
/*****************************************************************************/push ebp mov ebp, esp db “example_1”, 0x00db “HelloWorld”, 0x00db “user32.dll”, 0x00 lea ebx, [ebp-24h] push ebx mov ebx, 0x7c801d7b call ebx // LoadLibraryA/*****************************************************************************/
因为三个字符串为数据,而不是指令,不可能夹在指令中间,这样会让CPU将数据当做指令运行,程序跑飞。因此,只能放在指令区域之外。但是,又必须放在代码段中,因为Shellcode只有指令,没有数据段。因此,有了下面这种经典的做法:将字符串定义放置到一条CALL指令之后,由于CALL指令会将返回地址压栈,此时压入栈中的地址就为第一个字符串的地址,从而,我们可以在此后的代码中在栈上获取该字符串的地址。如下结构:
/*****************************************************************************/ JMP short GetStringRunMsgBox:...GetString:CALL RunMsgBoxDB “example_1”DB “HelloWorld”/*****************************************************************************/
这种结构就充分说明了指令和数据并不区分,本来CALL指令用来在栈上保存指令,结果现在被用来保存数据了。
下面就是利用上述结构编写的汇编程序:
/*****************************************************************************/// example_8 nasm下的汇编ShellcodeSECTION .textBITS 32global _main_main: jmp short GetStringRunMsgBox: pop ebx push ebx ; "user32.dll" mov eax, 0x7c801d7b ; LoadLibraryA call eax xor eax,eax push eax lea ebx, [ebx+11] ; "example_1" push ebx lea ebx, [ebx+10] ; "HelloWorld" push ebx push eax mov ebx, 0x77d507ea ; MessageBoxA call ebx push eax mov ebx, 0x7c81cafa ; ExitProcess call ebx GetString: call RunMsgBox db "user32.dll", 0x00 db "example_1", 0x00 db "HelloWorld", 0x00/*****************************************************************************/
RunMsgBox中第一句pop ebx就将“user32.dll”的首地址保存在了ebx,这里注意与栈不同,后面的ebx地址是加而不是减。使用命令:
nasm -f win32 example_8.asm
编译为obj文件。然后使用VS的cl.exe,链接为exe:
cl example_8.obj libcmt.lib
运行exe,成功:
图34
下面我们在Immunity Debugger来看看:
图35
这一段就是完整的代码,可见,字符串数据全部被反汇编为指令了,上图中标出了三个字符串的结尾符。
标出了结尾符之后,问题也就来了,是的,空字节,又出现了空字节,而且这次更不好处理,因为我们只用了字符串的首地址。为了不出现空字节,我们定义字符串的时候不能加0x00结束符,但是使用字符串的时候又需要该结束符,而且,这样定义的字符串位于代码段,代码段是不可写的,也就是一旦定义,不可修改。所以,如果空字节会引起问题,就不要这样定义。使用直接压栈的方法反而容易处理。
使用nasm有个好处,就是可以直接编译为bin格式,即操作码,例如:
nasm -f bin -o example_8.bin example_8.asm
用HexEdit打开example_8.bin,如下:
图36
这样,可以简单的写个程序将bin文件写出为Shellcode,就不用再去Immunity Debugger一个字节一个字节的抠出来了。
- 栈溢出笔记1.5 换一个汇编工具
- 栈溢出笔记1.5 换一个汇编工具
- 汇编溢出
- 一个栈溢出问题
- 关于栈溢出笔记
- 计算机基础知识--汇编溢出
- 汇编 溢出 解析
- 汇编 溢出的判断
- 一个栈溢出的BUG
- 一个栈溢出的实验
- 一个菜鸟作的一点汇编笔记
- 一个菜鸟作的一点汇编笔记
- 栈溢出笔记(1)
- 栈溢出笔记1.11 SafeSEH
- 栈溢出笔记1.11 SafeSEH
- 如何利用Capstone引擎写一个Android反汇编工具
- 学习ARM反汇编工具objdump和一个简单实例
- 8086汇编不溢出除法
- 今天学了表单
- 链表之带头结点的单链表就地逆置
- javascript的函数作用域及声明提前
- 20160409
- dubbox 的各种管理和监管
- 栈溢出笔记1.5 换一个汇编工具
- java线程
- leetcode Count and say
- 调试记录:The public type <<classname>> must be defined in its own file
- 各种排序算法
- 二叉树的层次遍历
- Apache 禁止访问
- nyoj 12 喷水装置(二)
- HDU 1583 DNA Assembly(暴力模拟)