美文网首页
【Microsoft】Windows Md5 消息摘要功能

【Microsoft】Windows Md5 消息摘要功能

作者: Kernel32 | 来源:发表于2018-03-09 23:13 被阅读0次

    前言

    最近写个东西玩玩,需要用到MD5,找了半天,发现MS的MD5连个接口都没有。当然事后goolge baidu还是找到了,可能用得小。openssl也可以,不过为了这些小功能去找个瑞士军刀代码,也是无聊(笑)。

    正文

    图像 1.png

    其实MS是有这个接口,不过没有暴露出来,在ntdll中导出函数能找到。当然是不知到形参之类的,怎么办? 只能找标准,rfc1321是MD5 的标准,里面有个MD5的实现。大概如下:

    
    /* MD5 context. */
    typedef struct {
      UINT4 state[4];                                   /* state (ABCD) */
      UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
      unsigned char buffer[64];                         /* input buffer */
    } MD5_CTX;
    
    void MD5Init PROTO_LIST ((MD5_CTX *));
    void MD5Update PROTO_LIST
      ((MD5_CTX *, unsigned char *, unsigned int));
    void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
    
    

    当然,对于巨硬大佬不跟标准早有所闻,我是不相信这么简单的。事实上,照上面的代码来,反汇编跟进MD5Init时,你可以发现state与count的位置刚好倒转。只好继续google(笑),后来找到个软件 Process hacker 的 doc,有个详细的MD5_CTX的结构,试了下还真能用,代码风格跟巨硬一个样。

    typedef struct MD5state_st
    {
        ULONG i[2];
        ULONG buf[4];
        UCHAR in[64];
        UCHAR digest[16];
    } MD5_CTX;
    

    其中,digest是MD5缓存,最后输出的地方,所以MD5Final只接受单个参数。最后大概就是这样:

    #include <windows.h>
    #include <tchar.h>
    
    
    #pragma pack(push,1)
    typedef struct MD5state_st
    {
       ULONG i[2];
       ULONG buf[4];
       UCHAR in[64];
       UCHAR digest[16];
    } MD5_CTX;
    #pragma pack(pop)
    
    typedef void (__stdcall *PMD5Init)(MD5_CTX *);
    typedef void (__stdcall *PMD5Update)(MD5_CTX *, void*, ULONG);
    typedef void (__stdcall *PMD5Final)( MD5_CTX *);
    
    __declspec(dllexport)
    void __stdcall MD5Init(MD5_CTX *c) {
       HMODULE ntdll = GetModuleHandle(_T("ntdll.dll"));
       if (!ntdll)return;
       PMD5Init ntdll_MD5_Init = (PMD5Init)GetProcAddress(ntdll, "MD5Init");
       ntdll_MD5_Init(c);
    }
    
    __declspec(dllexport)
    void __stdcall MD5Update(MD5_CTX *c, void * data, ULONG len) {
       HMODULE ntdll = GetModuleHandle(_T("ntdll.dll"));
       if (!ntdll)return;
       PMD5Update ntdll_MD5_Update = (PMD5Update)GetProcAddress(ntdll, "MD5Update");
       ntdll_MD5_Update(c, data,len);
    }
    
    
    __declspec(dllexport)
    void __stdcall MD5Final( MD5_CTX *c) {
       HMODULE ntdll = GetModuleHandle(_T("ntdll.dll"));
       if (!ntdll)return;
       PMD5Final ntdll_MD5_Final = (PMD5Final)GetProcAddress(ntdll, "MD5Final");
       ntdll_MD5_Final(c);
    }
    

    这里不用LoadLibrary,因为每个进程都会加载ntdll,所以直接GetModuleHandle就可以。__stdcall标准call,巨硬亲儿子,dll一般都是用这个调用约定,也可以反汇编跟进函数,看看是不是函数自己清栈,不明白可以查下调用约定,相互调用的知识点。

    结尾

    最后,免不了放个 Window MD5 的github,顺便介绍下 “巨硬的加密function Cryptography Reference” 和 “Process hacker 的doc”,挺有用的东西。


    编辑于 【2018.3.9】

    相关文章

      网友评论

          本文标题:【Microsoft】Windows Md5 消息摘要功能

          本文链接:https://www.haomeiwen.com/subject/eulmfftx.html