isno的一个找任意进程中JMP ESP/EBX指令的小程序

没什么用,方便找到比较通用的地址
/
// 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's pathname to the remote process'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=='ZM'&& *(WORD *)(imgbase+*(int *)(imgbase+0x3c))=='EP')
        {
            //利用PE格式定位映象名字
            fnbase=*(int *)(imgbase+*(int *)(imgbase+0x3c)+0x78)+imgbase;
            k=*(int *)(fnbase+0xc)+imgbase;
            //判断是否为KERNEL32
            if(*(int *)k =='NREK'&&*(int *)(k+4)=='23LE')
            {
                libhandle=imgbase;
                k=imgbase+*(int *)(fnbase+0x20);
                for(l=0;l<*(int *) (fnbase+0x18);++l,k+=4)
                {
                    //找到GetProcAddress函数
                    if(*(int *)(imgbase+*(int *)k)=='PteG'&&*(int *)(4+imgbase+*(int *)k)=='Acor')
                    {
                        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[i];
       if(temp==0xe8){
         k=*(int *)(shellbuff+i+1);
         calladd=fnadd;
         calladd+=k;
         calladd+=i;
         calladd+=5;
         if(calladd==chkesp){
             shellbuff[i]=0x90;
             shellbuff[i+1]=0x43;   // inc ebx
             shellbuff[i+2]=0x4b;   // dec ebx
             shellbuff[i+3]=0x43;
             shellbuff[i+4]=0x4b;
         }
      }
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值