zoukankan      html  css  js  c++  java
  • PE Checksum Algorithm的较简实现

    这篇BLOG是我很早以前写的,因为现在搬移到CNBLOGS了,经过整理后重新发出来。

    工作之前的几年一直都在搞计算机安全/病毒相关的东西(纯学习,不作恶),其中PE文件格式是必须知识。有些PE文件,比如驱动,系统会在加载时对checksum进行校验,确保驱动文件的完整性。关于PE文件如何校验,网上有很多资料可以学习,这里有一篇文章《An Analysis of the Windows PE Checksum Algorithm》是对WINDOWS API  CheckSumMappedFile进行逆向分析的。文章的结尾提到WINDOWS的这个校验和算法和IP协议的校验和算法类似,IP的校验和算法实现是RFC1071,如果对其他的校验和算法感兴趣,可以阅读WIKI的《Error Detection and correction》。

    但是CheckSumMappedFile的实现略显复杂,不够直观,后来读WRK的代码时,发现了WINDOWS内核在加载驱动时实现的校验和算法要简洁直观很多,分享给大家:

    uint32_t calc_checksum(uint32_t checksum, void *data, int length) {
        if (length && data != nullptr) {
            uint32_t sum = 0;
            do {
                sum = *(uint16_t *)data + checksum;
                checksum = (uint16_t)sum + (sum >> 16);
                data = (char *)data + 2;
            } while (--length);
        }
    
        return checksum + (checksum >> 16);
    }
    
    uint32_t generate_pe_checksum(void *file_base, uint32_t file_size) {
        uint32_t file_checksum = 0;
        PIMAGE_NT_HEADERS nt_headers = ImageNtHeader(file_base);
        if (nt_headers) {
            uint32_t header_size = (uintptr_t)nt_headers - (uintptr_t)file_base +
                ((uintptr_t)&nt_headers->OptionalHeader.CheckSum -
                (uintptr_t)nt_headers);
            uint32_t remain_size = (file_size - header_size - 4) >> 1;
            void *remain = &nt_headers->OptionalHeader.Subsystem;
            uint32_t header_checksum = calc_checksum(0, file_base, header_size >> 1);
            file_checksum = calc_checksum(header_checksum, remain, remain_size);
            if (file_size & 1){
                file_checksum += (uint16_t)*((char *)file_base + file_size - 1);
            }
        }
    
        return (file_size + file_checksum);
    }
  • 相关阅读:
    利用SVN进行个人代码管理
    ECEF坐标系
    地理坐标系、大地坐标系、投影坐标系
    让VS能够识别我的DLL运行库
    cannot convert parameter 1 from 'const char *' to 'LPCWSTR' 修改
    创建文件目录C++ windows
    GDAL获取遥感图像基本信息
    全球经纬度划分
    遥感影像度与米的转换
    C++ assert用法
  • 原文地址:https://www.cnblogs.com/concurrency/p/3926698.html
Copyright © 2011-2022 走看看