首页
社区
课程
招聘
[求助]第一次写程序遇到难题,请指教(关于文件操作)
发表于: 2008-9-8 10:11 5434

[求助]第一次写程序遇到难题,请指教(关于文件操作)

2008-9-8 10:11
5434
以前从没有写过程序,琢磨好几天了,还是解决不了下面的问题,请指教

1.如何搜索文件是否含有特征字符串?
2.谢谢指教!!!

问题很菜,见笑啦

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
2
从缓冲区读到的第一个字符开始,使用memcmp做匹配验证即可,不匹配就将缓冲区指针移动一个字节,重复直至找到为止
2008-9-8 12:22
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
多谢指教!

基本上完成了,

如果目标程序小的话,可以正常工作,太大的话,程序崩溃了

现在只剩下找崩溃的原因了
2008-9-8 17:53
0
雪    币: 204
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
缓冲区溢出了
2008-9-9 01:17
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
5
CreateFile----GetFileSize--ReadFile--strstr  没了。
2008-9-10 11:16
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
6
读文件的时候,应该用GeiFileSize动态读取,而不是定义一个缓冲区。
2008-9-10 11:18
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
因为有个bug,所以会崩溃,如果有空的话,不妨看看,看能不能找到

(我用ollydbg动态调试找到原因了

编译器:RadASM 2.2.13

代码如下:
#include "iostream"
#include <windows.h>

using namespace std;




void Pach(char *filename)

{

HANDLE hFile,hMap; //文件句柄
DWORD dwTmp; //文件大小
DWORD lpBuf; //读入文件的缓冲区
DWORD ReadLen; //实际读入长度
DWORD BytesWritten;//实际写入文件的字节数量
DWORD SizeHigh; //Long,用于装载一个64位文件长度的头32位。如这个长度没有超过2^32字节,则该参数可以设为NULL(变成ByVal)

DWORD *po; //po指针为特征代码开始地址


static char Src1[] = "\x53\x8B\x5C\x24\x08\x33\xC0\x85\xDB\x74\x58\x57"; //第一个特征
static char dst1[] = "\xB8\xC8\x00\x00\x00\xC3\x90\x90\x90\x90\x90\x90"; //待替换代码

char str1[]="a";

hFile = CreateFile(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (INVALID_HANDLE_VALUE == hFile)
{

CloseHandle(hFile);
printf("无法打开文件%s\n",filename);

}

else
{


//取文件大小
dwTmp = GetFileSize(hFile,&SizeHigh);
//分配内存

if ( (hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,0,0, NULL)) == NULL )

{
CloseHandle(hFile);
}
else
{

po=( DWORD *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0) ;



for(DWORD i=0;i<dwTmp;i++)
{
if(!memcmp(po,Src1,sizeof(Src1)-1))
{


//替换第一个特征
printf("%s",str1);
memcpy(po,dst1,sizeof(dst1)-1);


}

po=po+1;

}





}



//写入文件...
CloseHandle(hFile);
hFile = CreateFile(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,TRUNCATE_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(hFile,(LPVOID)lpBuf,dwTmp,&BytesWritten,NULL);

//释放内存

VirtualFree((LPVOID)lpBuf,0,MEM_RELEASE);

}


}

void SearchFiles(char *szDir)
{


HANDLE hFind;
WIN32_FIND_DATA FindFileData;
char szDirTmp[MAX_PATH]; //目标目录
char szDirTmp1[MAX_PATH];//目标文件


DWORD BytesWritten;

strcpy(szDirTmp,szDir);
if (szDir[strlen(szDirTmp)-1] != '\\')
{
strcat(szDirTmp,"\\");
}
strcat(szDirTmp,"*.*");




hFind = FindFirstFile(szDirTmp,&FindFileData);

if (hFind != INVALID_HANDLE_VALUE)
{


do
{
if (((*(DWORD *)FindFileData.cFileName &0xFFFF) != 0x2E) && ((*(DWORD *)FindFileData.cFileName &0xFFFFFF) != 0x2E2E))
{

strcpy(szDirTmp1,szDir);
strcat(szDirTmp1,"\\");
strcat(szDirTmp1,FindFileData.cFileName);
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
//继续搜索子目录
SearchFiles(szDirTmp1);

}

else
{

//补丁待破解文件

if(GetFileAttributes(szDirTmp1)==0x21)
{
//过滤只读文件
}
else{

//开始打补丁


//只补丁*.exe 和*.dll,这里图省事,简单判断了一下^_^
if (FindFileData.cFileName[strlen(FindFileData.cFileName)-1] == '\l'||FindFileData.cFileName[strlen(FindFileData.cFileName)-1] == '\e')
{printf("\n%s\n",FindFileData.cFileName);
Pach(szDirTmp1);
}
}
}
}
}while(FindNextFile(hFind,&FindFileData));


FindClose(hFind);

}

else
printf("未找到文件...");



}



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

char OBJ_path[255];


cout<< "按任意键开始...\n";
cin.get();



//取当前目录
GetCurrentDirectory(255,OBJ_path);

//在当前目录搜索文件并pach
SearchFiles(OBJ_path);

cout<< "\n按任意键结束...\n";
cin.get();

return 0;
}
2008-9-11 08:38
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
1)  UnmapViewOfFile

2)  for(DWORD i=0;i<dwTmp;i++)
     改成
   for(DWORD i=0;i<dwTmp-(sizeof(Src1)-1)+1;i++)
     或者
   for(DWORD i=0;i<=dwTmp-(sizeof(Src1)-1);i++)
     因为外层循环应该是比较到 (文件长度 - 字符串长度 + 1) 而不是 文件长度,不然 memcmp 会越界 (不过应该没有exe或dll小于你的那个12字节吧,呵呵,不然还要做更多检查)

3)  WriteFile(hFile,(LPVOID)lpBuf,dwTmp,&BytesWritten,NULL);
      lpBuf没赋值?至少你帖的这部分代码没有。。。
2008-9-11 11:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
天哪,这么多错误,我一点也看不出来

文件搜索的那段是从ccfer大侠那里复制过来的(那个金山杯2007逆向赛里的杀毒部分)
我把他的
lpBuf = (DWORD)VirtualAlloc(NULL, dwTmp, MEM_COMMIT, PAGE_READWRITE);
ReadFile(hFile,(LPVOID)lpBuf,dwTmp,&ReadLen,NULL);
改掉了,后面又忘了删掉了,顾此失彼

UnmapViewOfFile是由于删除多余代码的时候不小心删掉了,我总共替换了四个特征的,太大意了

我指的bug是
po=po+1;
并不像我想象的那样工作,在反汇编调试的时候发现,它竟然每次递增4,不知道是什么原因
改正后,就可以正常运行了,结果也正确

第一次编程,漏洞百出,多谢大侠们指点了
2008-9-11 13:56
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
po声明的时候你用的是DWORD指针,对指针操作+1,就是加指针指向的数据类型的长度,所以是加4,一般对内存字节操作用 BYTE 指针,这样一次+1。
2008-9-11 15:06
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
再次感谢指教,正如您所说的,现在不用手动改汇编代码了

昨天成功给程序加了个对话框,很有成就感

今天想解决一下特征码里是否能用通配符,但愿一切顺利,也祝您工作顺利
2008-9-12 09:11
0
游客
登录 | 注册 方可回帖
返回
//