循环渐进NsDoor(五)

虚拟机已经配好了,开发环境好了,剩下的就是不辞辛苦,写代码的事情了
­
高级语言写程序大家都见过,汇编也有一部分人用,但是用的不多,但是反汇编的魅力却很少有人注意
­
首先要说下shellcode的原理吧
基础知识应该是C++ASM
­
随便贴段代码《缓冲区溢出教程》:
#include<windows.h> 
­
int main() 

LoadLibrary(“msvcrt.dll”); 
system(“command.com”); 
­
    
return 0

//这个是开DOS窗口的代码,没什么普通,典型语法糖….. 
#include <windows.h> 
#include 
<winbase.h> 
­
typedef 
void (*MYPROC)(LPTSTR);        //定义函数指针 
­
int main() 

HINSTANCE LibHandle; 
MYPROC ProcAdd; 
LibHandle 
= LoadLibrary(“msvcrt.dll”); 
ProcAdd 
= (MYPROC) GetProcAddress(LibHandle, "system"); //查找system函数地址 
(ProcAdd) ("command.com");          //其实就是执行system(“command.com”) 
­
return 0
这段代码实现上面那段一样的功能,但是语法糖成分少了许多
PS:这段代码其实是有BUG的,我测试过,压入的数据有问题,不应该是字符串,应该是付给它个正确的地址….
仔细看下,应该发现些许程序执行的原理
­
任何程序代码都是要压入内存的,ASM中是code segment
代码段也是地址啊,所以调用函数,就是call
Call函数的地址而已,这是写把高级语言转换成shellcode的基础
­
­
现在转向要分析的reverse.cpp
先分析出这个文件中调用的所有函数:
­
有这些个函数:
­
­
自然每个函数对应一个地址,明白windows一点原理的应该知道,这些函数的地址是固定的(在各个版本系统内应该是固定的)
我用的是XP SP3,本机VISTA下地址和XP就不一样了,如何做到宇宙通用版的函数地址?这个是shellcode的高级技术,我只听说过,等以后认真学习了汇编再尝试下,呵呵
­
如何找到这些函数的地址呢,我写了个程序:
 
//address.cpp 
#include<iostream> 
#include
<windows.h> 
using namespace std; 
­
typedef 
void (*MYPROC)(LPWSTR); 
int main() 

         
char adrStr[200]; 
         HINSTANCE LibHandle; 
         MYPROC ProcAdd; 
­
    cout
<<"                           Function Address Hunter            "<<endl; 
         
while(true
         { 
                   cout
<<"The Dll name:"
                   cin
>>adrStr; 
                   LibHandle 
= LoadLibraryA(adrStr); 
                   cout
<<LibHandle<<endl<<endl; 
                   cout
<<"Function Name:"
                   cin
>>adrStr; 
­
                   
while(strncmp(adrStr,"exit",4!= 0
                   { 
                                      ProcAdd 
= (MYPROC)GetProcAddress(LibHandle,adrStr); 
                                      cout
<<ProcAdd<<endl; 
                                      cout
<<"Function Name:"
                                      cin
>>adrStr; 
                   } 
         }         
­
         
return 0

­
测试报告:
VISTA下的
­
­
XP SP3下的:
­
­
地址还是不一样的哈
对了,这个函数地址查询你要确定函数所在的dll,其实这个还算简单,网上一搜就知道了
说个比较特殊的
Memset这个函数是在ntdll中,比较例外的一个
找到了地址就成功了很多
我们可以把地址压入栈,然后call地址就行了,相当于调用了函数
但是函数的参数怎么得到,这是个问题,而且涉及了很多调试的技巧
下面虚拟个例子:
假设是Sleep200
这个函数,首先分析Sleep在哪个dll
发现实在kernel32中,用上面的程序查找出Sleep的地址:
0x7C802446
参数怎么构造的?
涉及汇编语言了,原理就是读取最近压入 的数据
所以你可以明白为什么函数的参数是从又向左压入栈了….
程序中的
Sleep(200);
现在替换掉:
_asm
{
   Push 200
   Mov eax, 0x7C802446
   Call eax
}
随便找个程序插入测试,完全可以通过,这就是构造参数
其实这中间过程也蛮复杂的,要注意各个寄存器的数值的变化,例如EIP,记录程序执行位置,ESP记录堆栈顶,EAX记录返回值等等
后面我还会用到EBP记录这些地址数据
­
额…
再接再厉,后面还有三篇要写
­
­
                                   --------------by   NewSketcher
                                               Time :   080822  15:55
posted @ 2008-10-04 13:02  端木  阅读(222)  评论(0编辑  收藏  举报