首页
社区
课程
招聘
请教在VC中写补丁文件的问题。
发表于: 2004-7-9 23:53 4831

请教在VC中写补丁文件的问题。

2004-7-9 23:53
4831
看到网上好多大侠们写的补丁程序,用起来很方便,于是也想自己也写一个,比如像我等小菜们肯定爆破的软件要比能写出注册机的软件要多得多,于是补丁程序就派上了用场。
    可是,小弟不才,在网上找了很久也没有看到比较系统介绍这方面的文章,于是自己尝试,先用CFile类的open函数得到要打补丁文件的句柄,(或者应该说是获得指向目标文件的指针更准确),然后用Seek定位文件,其中第一个参数就是将要打补丁的位置,也就是我们的文件指针的移动位置,然后再用Read函数将数据读到内存中,再用Write把修改后的数据写回去。这是我自己想的大概流程,可是问题就来了,那就是文件指针的定位。我们知道,PE文件在磁盘上存放时和在内存中的数据的地址是不同的,这样的话我该如何得到数据在内存中的地址呢?比如我用W32DASM中看到了要改写的数据的offset是0x1559,那么我应该怎样来计算出这段数据在内存中的地址并修改呢?如果要修改的话,我应该怎样操作这段数据呢?
    诚待指教!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
支持
分享
最新回复 (7)
雪    币: 519
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
2
OA->VA
可以WriteProcessMemery
2004-7-10 08:36
0
雪    币: 231
活跃值: (465)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
很多书上都有啊

而且网上很多教材di

多看看吧

呵呵

我是懒得写了

(其实是写不来:)
2004-7-10 12:53
0
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
4
最初由 RoBa 发布
OA->VA
可以WriteProcessMemery


OA->VA,能具体说明一下怎么转换吗?谢谢。
2004-7-11 14:09
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
5
罗云彬大哥写的
		.const
szNotFound	db	'无法查找',0
		.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 将 RVA 转换成实际的数据位置
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RVAToOffset	proc	_lpFileHead,_dwRVA
		local	@dwReturn

		pushad
		mov	esi,_lpFileHead
		assume	esi:ptr IMAGE_DOS_HEADER
		add	esi,[esi].e_lfanew
		assume	esi:ptr IMAGE_NT_HEADERS
		mov	edi,_dwRVA
		mov	edx,esi
		add	edx,sizeof IMAGE_NT_HEADERS
		assume	edx:ptr IMAGE_SECTION_HEADER
		movzx	ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
		.repeat
			mov	eax,[edx].VirtualAddress
			add	eax,[edx].SizeOfRawData		;eax = Section End
			.if	(edi >= [edx].VirtualAddress) && (edi < eax)
				mov	eax,[edx].VirtualAddress ;eax= Section start
				sub	edi,eax			;edi = offset in section
				mov	eax,[edx].PointerToRawData
				add	eax,edi			;eax = file offset
				jmp	@F
			.endif
			add	edx,sizeof IMAGE_SECTION_HEADER
		.untilcxz
		assume	edx:nothing
		assume	esi:nothing
		mov	eax,-1
@@:
		mov	@dwReturn,eax
		popad
		mov	eax,@dwReturn
		ret

_RVAToOffset	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 查找 RVA 所在的节区
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetRVASection	proc	_lpFileHead,_dwRVA
		local	@dwReturn

		pushad
		mov	esi,_lpFileHead
		assume	esi:ptr IMAGE_DOS_HEADER
		add	esi,[esi].e_lfanew
		assume	esi:ptr IMAGE_NT_HEADERS
		mov	edi,_dwRVA
		mov	edx,esi
		add	edx,sizeof IMAGE_NT_HEADERS
		assume	edx:ptr IMAGE_SECTION_HEADER
		movzx	ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
		.repeat
			mov	eax,[edx].VirtualAddress
			add	eax,[edx].SizeOfRawData		;eax = Section End
			.if	(edi >= [edx].VirtualAddress) && (edi < eax)
				mov	eax,edx			;eax= Section Name
				jmp	@F
			.endif
			add	edx,sizeof IMAGE_SECTION_HEADER
		.untilcxz
		assume	edx:nothing
		assume	esi:nothing
		mov	eax,offset szNotFound
@@:
		mov	@dwReturn,eax
		popad
		mov	eax,@dwReturn
		ret

_GetRVASection	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2004-7-11 15:04
0
雪    币: 519
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
6
不好意思打错了
是FO(File Offset)->VA(Virtual Address)
很多PE软件都有这个功能的.
2004-7-11 15:11
0
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
7
呵呵,谢谢大家的帮忙。我终于找到了一种比较简便的方法,这是较为简单的文件补丁,还有一种内存补丁我会继续研究,有结果再和大家分享。
    以下代码在VC6.0+WIN2000下编译通过。
   
    #include <stdio.h>
    main()
   {
      FILE *pFile = fopen("E:\\破解\\RegisterTest.exe", "r+b"); //此处为要打补丁的目标文件
      fseek(pFile, 0x1559, SEEK_SET);  // 定位文件偏移
      long lPos = ftell(pFile);    // 调试用于查看返回文件位置,此句可以省略
  
      char szFlag[2];
      fread(szFlag, 1, 2, pFile); // 可以在此处读出要改写的地方,注意此句过后文件指针向后移了2个字节
      fseek(pFile, -2, SEEK_CUR); // 将指针返回要改写的地方
      szFlag[0] = (char)0x90;    // 要替换的内容,这里将空操作写入
      szFlag[1] = (char)0x90;
      int nID = fwrite(szFlag, 1, 2, pFile);  // 写入文件,成功则返回写入的字节个数

      fclose(pFile);
      return 0;
   }

以上是小弟的瞎忙误撞的一点偶得,有失误愚钝之处还望大侠不吝赐教。
2004-7-12 22:29
0
雪    币: 295
活跃值: (461)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
8
最笨的方法是坐取出目?文件的??陪你要修改的??咄行比?(最好樘?)相同的地方咄行修改
2004-7-13 10:03
0
游客
登录 | 注册 方可回帖
返回
//