如何取得常量在文件中的偏移

WM13 2015-01-08 08:26:04
比如有个常量字符串
int main(void)
{
char a[]="hello world";//a数组保存的是“hello world”在栈区的一个副本 这里不关心a 关心的是常量区的hello world
printf("%s",a);
return 0;
}
正如大家知道的用十六进制编辑器改掉helloworld字符串,就可以修改显示结果
问如何在此程序中获得helloworld这个字符串在文件中的偏移,在运行时修改此字符串(使用的是文件操作,不考虑访问权限问题),再第二次运行时显示修改后的字符串?
...全文
386 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-01-10
  • 打赏
  • 举报
回复
个人意见:6楼代码有画蛇添足之嫌。
WM13 2015-01-10
  • 打赏
  • 举报
回复

#include <stdio.h>  
#include <windows.h>  
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>
FILE *f;
char cmd[256];
char fn[256];
char fn_old[256];
char fn_new[256];
char *b,*p;
int fl,i;
unsigned long GetFileoffset(const char*FileName,void*VirtualAddress)  
{   int pos=-1;
    FILE *fp;  
    IMAGE_DOS_HEADER DOS_header;            //DOS头结构  
    IMAGE_NT_HEADERS nt_header;             //PE头结构  
    IMAGE_SECTION_HEADER *psection_header;  //节表结构指针  
    fp=fopen(FileName,"rb");
    fread(&DOS_header,sizeof(struct _IMAGE_DOS_HEADER),1,fp);       
    fseek(fp,DOS_header.e_lfanew,0);  
    fread(&nt_header,sizeof(struct _IMAGE_NT_HEADERS),1,fp);
	unsigned long RVA=(unsigned long)VirtualAddress-nt_header.OptionalHeader.ImageBase; 
    psection_header = new IMAGE_SECTION_HEADER[nt_header.FileHeader.NumberOfSections];  
    fread(psection_header,nt_header.FileHeader.NumberOfSections*sizeof(struct _IMAGE_SECTION_HEADER),1,fp);
	for(int i=0;i<nt_header.FileHeader.NumberOfSections-1;i++)
	{
		if(psection_header[i].VirtualAddress<=RVA&&RVA>psection_header[i+1].VirtualAddress)
		{
			pos=i;
			break;
		}
	}
	if(pos==-1)pos=nt_header.FileHeader.NumberOfSections-1;
    unsigned long PointerToRawData=RVA-psection_header[pos].VirtualAddress+psection_header[pos].PointerToRawData;  
    fclose(fp);     
    return PointerToRawData;  
}  

int main() {
    char *a="hello world!";
    printf("%s",a);
    GetModuleFileName(NULL,fn,256);
    sprintf(fn_old,"%s_old",fn);
    sprintf(fn_new,"%s_new",fn);
    f=fopen(fn,"rb");
    if (NULL==f) {
        printf("Can not open file %s!\n",fn);
        return 1;
    }
    fl=filelength(fileno(f));
    b=(char *)malloc(fl);
    fread(b,1,fl,f);
    fclose(f);
    b[GetFileoffset(fn,a)]='G';
    f=fopen(fn_new,"wb");
    if (NULL==f) {
        printf("Can not create file %s!\n",fn_new);
        free(b);
        return 2;
    }
    fwrite(b,1,fl,f);
    fclose(f);
    free(b);
    if (!access(fn_old,0)) remove(fn_old);
    sprintf(cmd,"cmd.exe /c ren \"%s\" \"%s\"© \"%s\" \"%s\" >NUL 2>NUL",fn,strrchr(fn_old,'\\')+1,fn_new,fn);
    WinExec(cmd,SW_HIDE);
    return 0;
}

 
谢谢大神zhao4zhong1 的指点 ,在此基础上我修改了一下,让新人少走弯路,希望你不要介意。
fly_dragon_fly 2015-01-09
  • 打赏
  • 举报
回复
这没有办法吧
赵4老师 2015-01-09
  • 打赏
  • 举报
回复
最终版:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>
#include <windows.h>
FILE *f;
char cmd[256];
char fn[256];
char fn_old[256];
char fn_new[256];
char *b,*p;
int fl,i;
int main() {
    char a[]="hello world!1";

    printf("%s",a);

    GetModuleFileName(NULL,fn,256);
    sprintf(fn_old,"%s_old",fn);
    sprintf(fn_new,"%s_new",fn);
    f=fopen(fn,"rb");
    if (NULL==f) {
        printf("Can not open file %s!\n",fn);
        return 1;
    }
    fl=filelength(fileno(f));
    b=(char *)malloc(fl);
    fread(b,1,fl,f);
    fclose(f);
    for (i=0;i<fl-14;i++) {
        if (0==memcmp(b+i,"hello world!",12) && b[i+12]) {
            b[i+12]=0x63-b[i+12];
            break;
        }
    }
    f=fopen(fn_new,"wb");
    if (NULL==f) {
        printf("Can not create file %s!\n",fn_new);
        free(b);
        return 2;
    }
    fwrite(b,1,fl,f);
    fclose(f);
    free(b);
    if (!access(fn_old,0)) remove(fn_old);
    sprintf(cmd,"cmd.exe /c ren \"%s\" \"%s\"© \"%s\" \"%s\" >NUL 2>NUL",fn,strrchr(fn_old,'\\')+1,fn_new,fn);
    WinExec(cmd,SW_HIDE);

    return 0;
}
//C:\test>changemyself
//hello world!1
//c:\test>changemyself
//hello world!2
//c:\test>changemyself
//hello world!1
//c:\test>changemyself
//hello world!2
赵4老师 2015-01-09
  • 打赏
  • 举报
回复
//C:\test>changemyself
//hello world!1
//c:\test>changemyself
//hello world!2
//c:\test>changemyself
//hello world!1
//c:\test>changemyself
//hello world!2
赵4老师 2015-01-09
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>
#include <windows.h>
FILE *f;
char cmd[256];
char fn[256];
char fn_old[256];
char fn_new[256];
char *b,*p;
int fl,i;
int main(int argc,char **argv) {
    char a[]="hello world!1";

    printf("%s",a);

    sprintf(fn    ,"%s.exe",argv[0]);
    sprintf(fn_old,"%s_old.exe",argv[0]);
    sprintf(fn_new,"%s_new.exe",argv[0]);
    f=fopen(fn,"rb");
    if (NULL==f) {
        printf("Can not open file %s!\n",fn);
        return 1;
    }
    fl=filelength(fileno(f));
    b=(char *)malloc(fl);
    fread(b,1,fl,f);
    fclose(f);
    for (i=0;i<fl-14;i++) {
        if (0==memcmp(b+i,"hello world!",12) && b[i+12]) {
            b[i+12]=0x63-b[i+12];
            break;
        }
    }
    f=fopen(fn_new,"wb");
    if (NULL==f) {
        printf("Can not create file %s!\n",fn_new);
        free(b);
        return 2;
    }
    fwrite(b,1,fl,f);
    fclose(f);
    free(b);
    if (!access(fn_old,0)) remove(fn_old);
    sprintf(cmd,"cmd.exe /c ren \"%s\" \"%s\"© \"%s\" \"%s\" >NUL 2>NUL",fn,fn_old,fn_new,fn);
    WinExec(cmd,SW_HIDE);

    return 0;
}
此后三年 2015-01-08
  • 打赏
  • 举报
回复
你的意思是在生成的可执行文件中修改这个字符串?

70,017

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧