发新话题
打印

[转载]找到比较通用的jmpesp地址的代码

[转载]找到比较通用的jmpesp地址的代码

没什么用,方便找到比较通用的地址
/////////////////////////////////////////////////////
// Get JMP ESP/JMP EBX/CALL EBX Address in a Process
//           by isno
//      必须在VC下用DEBUG模式编译!!!
/////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>

#define FNENDLONG  0x08
#define NOPCODE   0x90
#define NOPLONG   0x0
#define BUFFSIZE  0x20000

#define SHELLBUFFSIZE 0x800
#define SHELLFNNUMS  9    //shellcode中的API函数数目+1

void   shellcodefn();
void   cleanchkesp(char *fnadd,char *shellbuff,char *chkesp,int len);

int main(int argc, char **argv)
{
//shellcode中要用到的字符串
char *str="LoadLibraryA""\x0"
  "GetModuleHandleA""\x0"
  "CreateFileA""\x0"
  "WriteFile""\x0"
  "CloseHandle""\x0"
  "ExitThread""\x0"
  "\x09""msvcrt.dll""\x0"
  "sprintf""\x0"
  "C:\\jmp.txt""\x0"
  "--JMP ESP ADDR--\r\n""\x0"
  "0x%.8x\r\n""\x0"
  "--JMP EBX ADDR--\r\n""\x0"
  "strend";

char *fnendstr="\x90\x90\x90\x90\x90\x90\x90\x90\x90";

char  buff[BUFFSIZE];
char  shellcodebuff[0x1000];
char  *shellcodefnadd,*chkespadd;
unsigned int bufflong;
unsigned int locklong;

int    i,k;
unsigned char temp;

HANDLE hProcess,  hToken;
TOKEN_PRIVILEGES  NewState;
DWORD ProcessId,  ReturnLength = 0;
TOKEN_PRIVILEGES  tp;
DWORD         dwProcessId;
PCWSTR       pszLibFile;
BOOL         fOk = FALSE; // Assume that the function fails
HANDLE       hThread = NULL;
PWSTR         pszLibFileRemote = NULL;

if(argc!=2)
{
   printf("usage: %s PID\n", argv[0]);
   printf("result is in C:\\jmp.txt\n");
   exit(0);
}
dwProcessId = atoi(argv[1]);

_asm{
   mov ESI,ESP
   cmp ESI,ESP
}
_chkesp();
chkespadd=_chkesp;
/*获得chkesp()函数的地址*/
temp=*chkespadd;
if(temp==0xe9) {
     ++chkespadd;
     i=*(int*)chkespadd;
     chkespadd+=i;
     chkespadd+=4;
}

//shellcode的地址
shellcodefnadd=shellcodefn;
//定位到实际shellcodefn()
temp=*shellcodefnadd;
if(temp==0xe9) {
   ++shellcodefnadd;
   k=*(int *)shellcodefnadd;
   shellcodefnadd+=k;
   shellcodefnadd+=4;
}
//找到shellcode的结尾
for(k=0;k<=0x1000;++k){
   if(memcmp(shellcodefnadd+k,fnendstr,FNENDLONG)==0)
     break;
}

//把shellcode代码复制进shellcodebuff
memcpy(shellcodebuff,shellcodefnadd,k);
//清除其中的chkesp()调用
cleanchkesp(shellcodefnadd,shellcodebuff,chkespadd,k);

//把字符串拷贝在shellcode的结尾
for(i=0;i<0x400;++i){
     if(memcmp(str+i,"strend",6)==0)
       break;
}
memcpy(shellcodebuff+k,str,i);

bufflong=k+i;    //shellcode的长度


///////////DEBUG/////////////////////
//_asm{
  // lea ecx, shellcodebuff
   //jmp ecx
//}
///////////DEBUG/////////////////////


//////////////////下面开始远线程写入///////////////////
  OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
  tp.PrivilegeCount = 1;
  LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
  tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
  CloseHandle(hToken);

  __try {
   // Get a handle for the target process.
   hProcess = OpenProcess(
     PROCESS_QUERY_INFORMATION |  // Required by Alpha
     PROCESS_CREATE_THREAD   |  // For CreateRemoteThread
     PROCESS_VM_OPERATION   |  // For VirtualAllocEx/VirtualFreeEx
     PROCESS_VM_WRITE,       // For WriteProcessMemory
     FALSE, dwProcessId);
   if (hProcess == NULL)
   {
     printf("OpenProcess failed!\n");
     __leave;
   }

   // Allocate space in the remote process for the pathname
   pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, bufflong, MEM_COMMIT, PAGE_READWRITE);
   if (pszLibFileRemote == NULL)
   {
     printf("VirtualAllocEx failed!\n");
     __leave;
   }

   // Copy the DLL&#39;s pathname to the remote process&#39;s address space
   if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) shellcodebuff, bufflong, NULL))
   {
     printf("WriteProcessMemory failed!\n");
     __leave;
   }

   // Create a remote thread that calls LoadLibraryW(DLLPathname)
   hThread = CreateRemoteThread(hProcess, NULL, 0, pszLibFileRemote, NULL, 0, NULL);
   if (hThread == NULL)
   {
     printf("CreateRemoteThread failed!\n");
     __leave;
   }
   
   // Wait for the remote thread to terminate
   //WaitForSingleObject(hThread, INFINITE);

   fOk = TRUE; // Everything executed successfully
   printf("result is in C:\\jmp.txt\n");
  }
  __finally { // Now, we can clean everthing up

   if (hThread != NULL)
     CloseHandle(hThread);

   if (hProcess != NULL)
     CloseHandle(hProcess);
  }
///////////////////////////////////////////////////////
return(0);
}

//shellcode实际功能代码
void shellcodefn()
{
  char    Buff[0x800];
  int     *except[3];

  FARPROC   sprintfadd;
  FARPROC   NOPNOP;
  FARPROC   ExitThreadadd;
  FARPROC   CloseHandleadd;
  FARPROC   WriteFileadd;
  FARPROC   CreateFileAadd;
  FARPROC   GetModuleHandleAadd;
  FARPROC    procloadlib;

  FARPROC   apifnadd[1];
  FARPROC   procgetadd=0;

  char    *stradd, *stradd1, *fmtstr;
  int     imgbase,fnbase,k,l;
  int     findaddr;
  HANDLE   libhandle;
  DWORD    ret;

  //建立异常处理为我们自己的异常处理代码
  _asm {
    //int 3
       mov eax, 1
       jmp  nextcall
     getstradd:
       pop  stradd
       lea  edi,except
       mov  eax,dword ptr FS:[0]
       mov  dword ptr [edi+0x08],eax
       mov  dword ptr FS:[0],EDI
  }
  stradd1=stradd;
  except[0]=0xffffffff;
  except[1]=stradd-0x07;

  //从这个地址开始搜索进程空间
  imgbase=0x77e00000;
  _asm{
   call getexceptretadd
  }
  for(;imgbase<0xbffa0000,procgetadd==0;)
  {
    //每次增加0x10000
    imgbase+=0x10000;
    if(imgbase==0x78000000)
      imgbase=0xbff00000;
    //判断是否PE格式
    if(*( WORD *)imgbase==&#39;ZM&#39;&& *(WORD *)(imgbase+*(int *)(imgbase+0x3c))==&#39;EP&#39;)
    {
      //利用PE格式定位映象名字
      fnbase=*(int *)(imgbase+*(int *)(imgbase+0x3c)+0x78)+imgbase;
      k=*(int *)(fnbase+0xc)+imgbase;
      //判断是否为KERNEL32
      if(*(int *)k ==&#39;NREK&#39;&&*(int *)(k+4)==&#39;23LE&#39;)
      {
        libhandle=imgbase;
        k=imgbase+*(int *)(fnbase+0x20);
        for(l=0;l<*(int *) (fnbase+0x18);++l,k+=4)
        {
          //找到GetProcAddress函数
          if(*(int *)(imgbase+*(int *)k)==&#39;PteG&#39;&&*(int *)(4+imgbase+*(int *)k)==&#39;Acor&#39;)
          {
            k=*(WORD *)(l+l+imgbase+*(int *)(fnbase+0x24));
            k+=*(int *)(fnbase+0x10)-1;
            k=*(int *)(k+k+k+k+imgbase+*(int *)(fnbase+0x1c));
            procgetadd=k+imgbase;
            break;
          }
        }
      }
    }
  }
//搜索KERNEL32.DLL模块地址和API函数 GetProcAddress地址
//利用异常处理来处理了搜索页面不在情况

  _asm{
    lea edi,except
    mov eax,dword ptr [edi+0x08]
    mov dword ptr fs:[0],eax
  }
  //恢复异常链  

  if(procgetadd==0)
    goto die;

  //利用GetProcAddress来获得shellcode中所用到的API地址
  for(k=1;k<SHELLFNNUMS;++k)
  {
    if(*stradd1==0x9)
      libhandle=GetModuleHandleAadd(stradd1+1);
    else
      apifnadd[k]=procgetadd(libhandle,stradd1);
    for(;;++stradd1)
    {
      if(*(stradd1)==0&&*(stradd1+1)!=0)
        break;
    }
    ++stradd1;
  }
  libhandle=CreateFileAadd(stradd1,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  stradd1+=11; //stradd1指向"--JMP ESP--\r\n"
  WriteFileadd(libhandle,stradd1,18,&ret,NULL);
  stradd1+=19; //stradd1指向"0x.8x\r\n"
  fmtstr=stradd1;
  stradd1+=9; //stradd1指向"--JMP EBX--\r\n"
  //////////////////////////////////////////////////////////
  //建立异常处理为我们自己的异常处理代码
  //get jmp esp
  _asm {
//    int 3
       lea  edi,except
       mov  eax,dword ptr FS:[0]
       mov  dword ptr [edi+0x08],eax
       mov  dword ptr FS:[0],EDI
  }
  except[0]=0xffffffff;
  except[1]=stradd-0x07;

  //从这个地址开始搜索进程空间
  _asm{
   //int 3
   xor ebx,ebx
   call getexceptretadd
   add ebx, 1000h
   cmp ebx, 80000000h
   jae gsleep1
   jmp loadmem1
findj1:
   inc ebx
loadmem1:
   mov al, byte ptr [ebx]
   cmp al, 0xff  // FF E4 = JMP ESP
   jnz findj1
   mov al, byte ptr [ebx+1]
   cmp al, 0xe4
   jnz findj1
   mov findaddr, ebx
  }
  sprintfadd(Buff, fmtstr, findaddr);
  WriteFileadd(libhandle,Buff,12,&ret,NULL);
  _asm{
    jmp findj1
gsleep1:
   xor ebx,ebx
   call getexceptretadd
   add ebx, 1000h
   cmp ebx, 80000000h
   jae gsleep2
   jmp loadmem2
findj2:
   inc ebx
loadmem2:
   mov al, byte ptr [ebx]
   cmp al, 0x54  // 54 C3 = PUSH ESP,RET
   jnz findj2
   mov al, byte ptr [ebx+1]
   cmp al, 0xC3
   jnz findj2
   mov findaddr, ebx
  }
  sprintfadd(Buff, fmtstr, findaddr);
  WriteFileadd(libhandle,Buff,12,&ret,NULL);
  _asm{
    jmp findj2
gsleep2:
    nop
  }
  //get jmp ebx
  WriteFileadd(libhandle,stradd1,18,&ret,NULL);
  //////////////////////////////////////////////////////////
  //从这个地址开始搜索进程空间
  _asm{
   //int 3
   xor ebx,ebx
   call getexceptretadd
   add ebx, 1000h
   cmp ebx, 80000000h
   jae gsleepb1
   jmp loadmemb1
findjb1:
   inc ebx
loadmemb1:
   mov al, byte ptr [ebx]
   cmp al, 0xff  //FF E3 = JMP EBX
   jnz findjb1
   mov al, byte ptr [ebx+1]
   cmp al, 0xe3
   jnz findjb1
   mov findaddr, ebx
  }
  sprintfadd(Buff, fmtstr, findaddr);
  WriteFileadd(libhandle,Buff,12,&ret,NULL);
  _asm{
    jmp findjb1
gsleepb1:
   nop
   xor ebx,ebx
   call getexceptretadd
   add ebx, 1000h
   cmp ebx, 80000000h
   jae gsleepb2
   jmp loadmemb2
findjb2:
   inc ebx
loadmemb2:
   mov al, byte ptr [ebx]
   cmp al, 0xff  //FF D3
   jnz findjb2
   mov al, byte ptr [ebx+1]
   cmp al, 0xd3
   jnz findjb2
   mov findaddr, ebx
  }
  sprintfadd(Buff, fmtstr, findaddr);
  WriteFileadd(libhandle,Buff,12,&ret,NULL);
  _asm{
    jmp findjb2
gsleepb2:
    nop
     xor ebx,ebx
   call getexceptretadd
   add ebx, 1000h
   cmp ebx, 80000000h
   jae gsleepb3
   jmp loadmemb3
findjb3:
   inc ebx
loadmemb3:
   mov al, byte ptr [ebx]
   cmp al, 0x53  // 53 C3 = PUSH EBX,RET
   jnz findjb3
   mov al, byte ptr [ebx+1]
   cmp al, 0xc3
   jnz findjb3
   mov findaddr, ebx
  }
  sprintfadd(Buff, fmtstr, findaddr);
  WriteFileadd(libhandle,Buff,12,&ret,NULL);
  _asm{
    jmp findjb3
gsleepb3:
    nop
  }
  CloseHandleadd(libhandle);
  ExitThreadadd(0x7fffffff);

//搜索KERNEL32.DLL模块地址和API函数 GetProcAddress地址
//利用异常处理来处理了搜索页面不在情况

  _asm{
    lea edi,except
    mov eax,dword ptr [edi+0x08]
    mov dword ptr fs:[0],eax
  }
  //恢复异常链
  //死循环
die:  
  goto die;

  //我们自己的异常处理代码,以解决搜索内存无效页面时的继续执行问题
   _asm{
getexceptretadd:
      pop eax
      push eax
      mov edi,dword ptr [stradd]
      mov dword ptr [edi-0x0e],eax
      ret
errprogram:
      mov eax,dword ptr [esp+0x0c]
      add eax,0xb8
      mov dword ptr [eax],0x11223344 //stradd-0xe,此地址会被修改
      xor eax,eax    //2
      ret      //1
execptprogram:
      jmp errprogram  //2 bytes stradd-7
nextcall:
      call getstradd  //5 bytes
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
    }
}

/*清除shellcode中的chkesp()调用代码*/
void cleanchkesp(char *fnadd,char *shellbuff,char *chkesp,int len)
{
  int i,k;
  unsigned char temp;
  char *calladd;

  for(i=0;i<len;++i){
    temp=shellbuff;
    if(temp==0xe8){
     k=*(int *)(shellbuff+i+1);
     calladd=fnadd;
     calladd+=k;
     calladd+=i;
     calladd+=5;
     if(calladd==chkesp){
       shellbuff=0x90;
       shellbuff[i+1]=0x43;  // inc ebx
       shellbuff[i+2]=0x4b;  // dec ebx
       shellbuff[i+3]=0x43;
       shellbuff[i+4]=0x4b;
     }
   }
  }
}


暴力搜索jmp esp的地址     呵呵,没事干写着玩,在shellcode的编写中,经常需要jmp esp的地址来覆盖eip的内容,

这个程序就是用来暴力搜索.dll中jmp esp的地址的,没什么技术含量,后边的容错处理

比较妙,不过不是我自己想的,参考了网上资料,大家谁对异常处理了解,拜托给我

讲讲。在xp下,vc++6.0编译通过,不过我试了下,居然kernel32里没jmp esp,不知道是

不是我程序的问题,大家检查检查。

#include <stdio.h>

#include <windows.h>

void use() { printf("usage:\n"); printf("jmpesp\t <dllname>\n"); }

int main(int argc, char *argv[]) {

HINSTANCE hHandle; BYTE *p; int count=0;

printf("************************************\n"); printf("***\n"); printf("*** Get address of Jmp ESP from dll\n"); printf("*** 专科生 2004.11.19\n"); printf("************************************\n\n\n");

if(argc!=2) use();

hHandle=LoadLibrary(argv[1]);

if(hHandle==NULL) { printf("Fail In Loading %s\n", argv[1]); return -1; }

p=(BYTE *)hHandle;

bool flag=false;

for(int i=0; !flag; i++) { try { if(p==0xFF && p[i+1]==0xE4) //jmp esp的二进制 { count++;

printf("The Address of jmp esp: 0x%x \n\n", p+i); } }

catch(...) { flag=true; }

} printf("Total Number of The Addresses In %s: %d\n\n", argv[1], count);

return 0; }

Heaven is a place nearby so I won&#39;t be so far away and if you try and look for me maybe you&#39;ll find me someday

TOP

发新话题