参考:http://www.mouseos.com/assembly/06.html

参考:http://www.cnblogs.com/tk091/archive/2012/04/18/2456174.html

typedef struct CV_INFO_PDB70
{
    DWORD CvSignature;
    GUID Guid;
    DWORD Age;
    //BYTE PdbFileName[];
    char PdbFilePath[MAX_PATH];
} CV_INFO_PDB70_T;

static const DWORD g_dwTimeStamp = 0x52C652E0;

// 一共有3个地方要replace
int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 3 || _tcscmp(argv[1], _T("-m")) != 0)
    {
        printf("cmdline format err.\n");
        return 0;
    }

_tprintf(_T("---------------\nprocess file %s.\n"), argv[2]);

FILE *fp;
    fp = _tfopen(argv[2], _T("rb+"));
    if (!fp)
    {
        printf("occur error -1,reason:%d\n", errno);
        return -1;
    }

// IMAGE_NT_HEADER address
    LONG e_lfanew;
    fseek(fp, 0x3c, SEEK_SET);
    fread(&e_lfanew, 4, 1, fp);

// Signature
    DWORD sign;
    fseek(fp, e_lfanew, SEEK_SET);
    fread(&sign, 4, 1, fp);
    if (sign != 0x00004550)
    {
        printf("PE header not matched,sign:%x\n---------------\n", sign);
        fclose(fp);
        return -2;
    }

// IMAGE_FILE_HEADER
    IMAGE_FILE_HEADER ifh;
    fseek(fp, e_lfanew + 4, SEEK_SET);
    fread(&ifh, sizeof(IMAGE_FILE_HEADER), 1, fp);

#ifdef _DEBUG
    printf("IMAGE_FILE_HEADER结构:\n");
    printf("Machine       : %04X\n", ifh.Machine);
    printf("NumberOfSections  : %04X\n", ifh.NumberOfSections);
    printf("TimeDateStamp    : %08X\n", ifh.TimeDateStamp);
    printf("PointerToSymbolTable : %08X\n", ifh.PointerToSymbolTable);
    printf("NumberOfSymbols   : %08X\n", ifh.NumberOfSymbols);
    printf("SizeOfOptionalHeader : %04X\n", ifh.SizeOfOptionalHeader);
    printf("Characteristics   : %04X\n", ifh.Characteristics);
    printf("\n");
#endif

// replace timestamp
    _tprintf(_T("replace %s timestamp,old : %08X, new : %08X.\n"), argv[2], ifh.TimeDateStamp, g_dwTimeStamp);
    ifh.TimeDateStamp = g_dwTimeStamp;
    fseek(fp, e_lfanew + 4, SEEK_SET);
    fwrite((void *)&ifh, sizeof(ifh), 1, fp);

// IMAGE_DIRECTORY_ENTRY_DEBUG
    LONG debugEntryAddr = e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER) + ifh.SizeOfOptionalHeader + (-10) * (long)sizeof(IMAGE_DATA_DIRECTORY);
    fseek(fp, debugEntryAddr, SEEK_SET);

// IMAGE_DATA_DIRECTORY
    IMAGE_DATA_DIRECTORY idd;
    fread(&idd, sizeof(IMAGE_DATA_DIRECTORY), 1, fp);

#ifdef _DEBUG
    printf("IMAGE_DIRECTORY_ENTRY_DEBUG结构:\n");
    printf("VirtualAddress : %08X\n", idd.VirtualAddress);
    printf("Size   : %08X\n", idd.Size);
    printf("IMAGE_DEBUG_DIRECTORY一共有%f个\n", 1.0 * idd.Size / sizeof(IMAGE_DEBUG_DIRECTORY));
    printf("\n");
#endif

// check the address valid or not
    if (idd.VirtualAddress == 0x00 || idd.Size == 0x00)
    {
        _tprintf(_T("Debug information not found in file %s, skip modify debug info.\n---------------\n"), argv[2]);
        fclose(fp);
        return 0;
    }

// IMAGE_DEBUG_DIRECTORY
    IMAGE_DEBUG_DIRECTORY idd2;
    fseek(fp, (WORD)idd.VirtualAddress, SEEK_SET); // need convert virtual address
    fread(&idd2, sizeof(IMAGE_DEBUG_DIRECTORY), 1, fp);

#ifdef _DEBUG
    printf("IMAGE_DEBUG_DIRECTORY结构:\n");
    printf("AddressOfRawData : %08X\n", idd2.AddressOfRawData);
    printf("Characteristics : %08X\n", idd2.Characteristics);
    printf("MajorVersion : %08X\n", idd2.MajorVersion);
    printf("MinorVersion : %08X\n", idd2.MinorVersion);
    printf("PointerToRawData : %08X\n", idd2.PointerToRawData);
    printf("SizeOfData : %08X\n", idd2.SizeOfData);
    printf("TimeDateStamp : %08X\n", idd2.TimeDateStamp);
    printf("Type : %08X\n", idd2.Type);
    printf("\n");
#endif

// replace timestamp
    _tprintf(_T("replace pdb timestamp, old : %08X, new : %08X.\n"), idd2.TimeDateStamp, g_dwTimeStamp);
    idd2.TimeDateStamp = g_dwTimeStamp;
    fseek(fp, (WORD)idd.VirtualAddress, SEEK_SET); // need convert virtual address
    fwrite((void *)&idd2, sizeof(idd2), 1, fp);

// CV_INFO_PDB70
    CV_INFO_PDB70_T cvInfo;
    fseek(fp, idd2.PointerToRawData, SEEK_SET);
    fread(&cvInfo, sizeof(CV_INFO_PDB70_T), 1, fp);

#ifdef _DEBUG
    printf("CV_INFO_PDB70结构:\n");
    printf("Age : %04X\n", cvInfo.Age);
    printf("CvSignature : %04X\n", cvInfo.CvSignature);
    printf("PdbFileName : %s\n", cvInfo.PdbFilePath);
    printf("Guid : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
        cvInfo.Guid.Data1, cvInfo.Guid.Data2, cvInfo.Guid.Data3,
        cvInfo.Guid.Data4[0], cvInfo.Guid.Data4[1], cvInfo.Guid.Data4[2],
        cvInfo.Guid.Data4[3], cvInfo.Guid.Data4[4], cvInfo.Guid.Data4[5],
        cvInfo.Guid.Data4[6], cvInfo.Guid.Data4[7]);
    printf("\n");
#endif

if (cvInfo.CvSignature != 0x53445352)   //RSDS
    {
        printf("pdb signature not matched, CvSignature:%x\n---------------\n", cvInfo.CvSignature);
        fclose(fp);
        return -2;
    }

// replace guid
    printf("replace pdb guid,old : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
        cvInfo.Guid.Data1, cvInfo.Guid.Data2, cvInfo.Guid.Data3, cvInfo.Guid.Data4[0],
        cvInfo.Guid.Data4[1], cvInfo.Guid.Data4[2], cvInfo.Guid.Data4[3], cvInfo.Guid.Data4[4],
        cvInfo.Guid.Data4[5], cvInfo.Guid.Data4[6], cvInfo.Guid.Data4[7]);
    //_tprintf(_T("replace pdb guid,old : %08X-%04X-%04X-%llX\n"), cvInfo.Guid.Data1, cvInfo.Guid.Data2, cvInfo.Guid.Data3, (__int64)cvInfo.Guid.Data4);
    __int64 tmp = 0xdc38466dca416db1;
    cvInfo.Guid.Data1 = 0xf363bf77;
    cvInfo.Guid.Data2 = 0xb00b;
    cvInfo.Guid.Data3 = 0x4fb0;
    memcpy(&cvInfo.Guid.Data4, &tmp, 8);

//_tprintf(_T("replace pdb guid,new : %08X-%04X-%04X-%llX\n"), cvInfo.Guid.Data1, cvInfo.Guid.Data2, cvInfo.Guid.Data3, tmp);
    printf("replace pdb guid,new : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
        cvInfo.Guid.Data1, cvInfo.Guid.Data2, cvInfo.Guid.Data3, cvInfo.Guid.Data4[0],
        cvInfo.Guid.Data4[1], cvInfo.Guid.Data4[2], cvInfo.Guid.Data4[3], cvInfo.Guid.Data4[4],
        cvInfo.Guid.Data4[5], cvInfo.Guid.Data4[6], cvInfo.Guid.Data4[7]);
    fseek(fp, idd2.PointerToRawData, SEEK_SET);
    fwrite((void *)&cvInfo, sizeof(cvInfo), 1, fp);

fclose(fp);

printf("---------------\n");
    //system("pause");
    getchar();

return 0;
}

Make the PE file consistent when code not changed的更多相关文章

  1. PE File.

    Figure 1 - PE File The CLR header stores information to indicate that the PE file is a .NET executab ...

  2. Delphi : Analyze PE file headers?

    Analyze PE file headers? { You'll need a OpenDialog to open a Exe-File and a Memo to show the file i ...

  3. Inject shellcode into PE file

    先声明这是不免杀的,只是演示. 哔哩哔哩视频 新增节 一般能实现特定功能的shellcode的长度都比较长,可以分到几个节上的空白区,但是这样麻烦啊,或者把最后一个节扩大,但是最后一个节一般没有执行的 ...

  4. 《Peering Inside the PE: A Tour of the Win32 Portable Executable File Format》阅读笔记二

    Common Sections The .text section is where all general-purpose code emitted by the compiler or assem ...

  5. dnSpy PE format ( Portable Executable File Format)

    Portable Executable File Format PE Format  微软官方的 What is a .PE file in the .NET framework? [closed] ...

  6. PE Header and Export Table for Delphi

    Malware Analysis Tutorial 8: PE Header and Export Table 2. Background Information of PE HeaderAny bi ...

  7. Reverse Core 第二部分 - 13章 - PE文件格式

    @date: 2016/11/24 @author: dlive ​ PE (portable executable) ,它是微软在Unix平台的COFF(Common Object File For ...

  8. 利用PE数据目录的导入表获取函数名及其地址

    PE文件是以64字节的DOS文件头开始的(IMAGE_DOS_HEADER),接着是一段小DOS程序,然后是248字节的 NT文件头(IMAGE_NT_HEADERS),NT的文件头位置由IMAGE_ ...

  9. Load PE from memory(反取证)(未完)

      Article 1:Loading Win32/64 DLLs "manually" without LoadLibrary() The most important step ...

随机推荐

  1. 什么是Socket:

    先了解一些前提: 网络由下往上分为 物理层 .数据链路层 . 网络层 . 传输层 . 会话层 . 表现层 和 应用层.通过初步了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对 ...

  2. java_3:JVM、JRE、JDK区别和联系

    首先 三者之间存在包含关系JVM + 核心类库 = JREJRE + java开发工具(javac.exe/jar.exe) = JDK 什么是JVM? 我们知道Java语言有一个独特的优点就是可以跨 ...

  3. 02-10Android学习进度报告十

    今天我学习了有关ListView的基础知识,主要是学习了其中界面展示的基本方法. 首先看一个简单的列表实现代码: public class Animal { private String aName; ...

  4. sparkRDD:第1节 RDD概述;第2节 创建RDD

    RDD的特点: (1)rdd是数据集: (2)rdd是编程模型:因为rdd有很多数据计算方法如map,flatMap,reduceByKey等: (3)rdd相互之间有依赖关系: (4)rdd是可以分 ...

  5. 一、log4j日志框架的理论和不同场景使用

    1.日志框架: 工作中要进行Java输出日志时,你需要一个或者多个日志框架.框架能提供对象.方法和必要的配置来发送日志信息.Java语言本身有自带的日志实现包java.util.logging.还有很 ...

  6. Color Space 和 Color Range

    颜色有两个属性Color Range和Color Space 有关Color Space的解释可以看下面两个链接: https://www.jianshu.com/p/facdbab5ac20 htt ...

  7. [GWCTF 2019]mypassword

    这道题(不只这道题以后也一定)要注意控制台中的信息,给出了login.js代码,会把当前用户的用户名和密码填入表单 注册个账号,登录之后给提示不是注入题 浏览一下网站功能,feedback页面可以提交 ...

  8. redis 之redis发布订阅

    Redis 通过 PUBLISH . SUBSCRIBE 等命令实现了订阅与发布模式. 一个Publisher,多个Subscriber模型 如下图所示,可以作为消息队列或者消息通道 主要应用: 一个 ...

  9. 大数据萌新的Python学习之路(一)

    笔记开始简介 从2018年9月份正式进入大学的时代,大数据和人工智能的崛起让我选择了计算机专业学习数据科学与大数据技术专业,接触的第一门语言就是C语言,后来因为同学推荐的原因进入了学校的人工智能研究协 ...

  10. Java日期时间API系列12-----Jdk8中java.time包中的新的日期时间API类,日期格式化,常用日期格式大全

    通过Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter, 可以看出java8的DateTimeFormatter完美解决 ...