http://tech.acnow.net/Html/Program/VC/VCShell/
原文是安全中国的yellow写的“深入剖析ShellCode”云云,在上面的地址可以找到,
但文中给出的例子不是无法编译,就是编译过后无法按想法执行,我将代码改变如下,可以执行,供大家参考。
__inline __declspec(naked) unsigned int __stdcall GetKernel32()
{
  __asm
  {
      push esi
      push ecx
      mov  esi,fs:0
      lodsd
GetExeceptionFilter:
      cmp [eax],0xffffffff
      je GetedExeceptionFilter  //如果到达最后一个节点(它的pfnHandler指向UnhandledExceptionFilter)
      mov eax,[eax]        //否则往后遍历,一直到最后一个节点
      jmp GetExeceptionFilter
GetedExeceptionFilter:
      mov eax, [eax+4]
FindMZ:
      and eax,0xffff0000      //根据PE执行文件以64k对界的特征加快查找速度
      cmp word ptr [eax],'ZM'    //根据PE可执行文件特征查找KERNEL32.DLL的基址
      jne MoveUp          //如果当前地址不符全MZ头部特征,则向上查找
      mov ecx,[eax+0x3c]
      add ecx,eax
      cmp word ptr [ecx],'EP'    //根据PE可执行文件特征查找KERNEL32.DLL的基址
      je Found          //如果符合MZ及PE头部特征,则认为已经找到,并通过Eax返回给调用者
MoveUp:
      dec eax            //准备指向下一个界起始地址
      jmp FindMZ
Found:
      pop ecx
      pop esi
      ret
  }
}
__inline __int32 __cdecl GetFunctionByName(__int32 ImageBase,const char*FuncName,int flen)
{
  unsigned int FunNameArray,PE, Count=0,IED,iedN;
  __asm
  {
      mov eax,ImageBase
      add eax,0x3c      //指向PE头部偏移值e_lfanew
      mov eax,[eax]      //取得e_lfanew值
      add eax,ImageBase    //指向PE header
      cmp [eax],0x00004550
      jne NotFound      //如果ImageBase句柄有错
      mov PE,eax
      mov eax,[eax+0x78]
      add eax,ImageBase
      mov IED,eax      //指向IMAGE_EXPORT_DIRECTORY
      mov eax,[eax+0x0c]
      add eax,ImageBase    //指向引出模块名,如果在查找KERNEL32.DLL的引出函数那么它将指向"KERNEL32.dll"
      mov iedN,eax
      mov eax,IED
      mov eax,[eax+0x20]
      add eax,ImageBase
      mov FunNameArray,eax  //保存函数名称指针数组的指针值
      mov ecx,IED
      mov ecx,[ecx+0x14]    //根据引出函数个数NumberOfFunctions设置最大查找次数
FindLoop:
      mov eax,[eax]
      add eax,ImageBase
      mov esi,FuncName
      mov edi,eax
      push ecx
      mov ecx,flen      //逐个字符比较,如果相同则为找到函数,注意这里的ecx值
      cld
      rep cmpsb
      jne FindNext      //如果当前函数不是指定的函数则查找下一个
      add esp,4        //如果查找成功,则清除用于控制外层循环而压入的Ecx,准备返回
      mov eax,IED
      mov eax,[eax+0x24]
      add eax,ImageBase
      shl Count,1  //根据AddressOfName计算索引,然后根据此索引查AddressOfNameOrdinals同样索引下的序号,再根据此序号为索引查AddressOfFunctions数组得到待求函数的地址。       add eax,Count
      mov eax,[eax]      
      and eax,0x0000ffff
      mov ebx,eax
      mov eax,IED
      mov eax,[eax+0x1c]
      add eax,ImageBase
      shl ebx,2
      mov eax,[eax+ebx]
      add eax,ImageBase
      jmp Found
FindNext:
      inc Count        //记录函数索引
      add FunNameArray,4
      mov eax,FunNameArray  //下一个函数名指针
      pop ecx          //恢复压入的ecx(NumberOfFunctions),进行计数循环
      loop FindLoop      //如果ecx不为0则递减并回到FindLoop,往后查找
NotFound:
      xor eax,eax        //如果没有找到,则返回0
Found:
  }
}void main()
{
  __int32 loadlibfun;
  char title[]="test",user32[]="user32",msgf[]="MessageBoxA";
  char fn1[]="LoadLibraryA";
  char fn2[]="MessageBoxA";
  
  loadlibfun=GetFunctionByName(GetKernel32(),fn1,12);
  __asm
  {
      lea eax,user32
      push eax
      call dword ptr loadlibfun  //相当于执行LoadLibrary("user32");      lea ebx,msgf
      push 0x0b          //"MessageBoxA"的长度
      push ebx
      push eax      call GetFunctionByName      mov ebx,eax
      add esp,0x0c        //GetFunctionByName使用C调用约定,由调用者调整堆栈
      push 0
      lea eax,title
      push eax
      push eax
      push 0
      call ebx          //相当于执行MessageBox(NULL,"test","test",MB_OK)
  }
}有没有哪位,能把顶上的连接中yellow的最后一个例子解释一下!
我只改了前面的例子,后面的看不懂!

解决方案 »

  1.   

    因为我还再用win98,所以上面的代码能再xp或2000中运行吗?谁试过的,告诉我好吗?
      

  2.   

    编译好的exe文件,右键属性,选择用兼容模式运行试试看。
      

  3.   

    breakind(冰舞,把练街舞的精神拿来编程,必有所成.) 
    XP下可以运行
    ----------------------------------------------------
    弹出了“test”对话框了!
    真的吗?
    我正在看一偏帖子讲如何绕过IE的运行activeX的警告。如果成功,我再帖出来,希望再帮忙看看。