最新Bin2Code框架CodeCMR论文解读
去年看过一篇用图神经网络进行二进制代码相似性分析的论文,主要的目标是把同一份源代码通过不同的编译器,不同的平台,不同的优化选项得到的不同的二进制代码找出来,有兴趣的同学可以看下论文和官方介绍。
论文链接:
https://keenlab.tencent.com/en/whitepapers/Ordermatters.pdf
官方介绍:
https://keenlab.tencent.com/zh/2019/12/10/Tencent-Keen-Security-Lab-Order-Matters/
最近他们又发了一篇论文,这次在上面任务的基础上升级了,主要是解决给出二进制代码,得到源代码的问题,这给了我这个逆向分析菜鸟一些希望。
论文提出了一个Bin2Code的端到端匹配框架CodeCMR,我们先来看看数据集。
训练的数据集主要由gcc-x64-O0和clang-arm-O3作为两种组合方式,生成了两个30000/10000/10000的训练/验证/测试集。
数据集下载:
https://github.com/binaryai/CodeCMR
我随机取了一个样本出来:
一个样本有33列,包括了不同编译器(gcc,clang),不同平台(x86 / x64 / arm / arm64)和不同编译选项的(O1 / O2 / O3)的32种组合。
下面为所有的列:
Index(['c_label', 'gcc-x86-O0', 'gcc-x86-O1', 'gcc-x86-O2', 'gcc-x86-O3','gcc-x64-O0', 'gcc-x64-O1', 'gcc-x64-O2', 'gcc-x64-O3', 'gcc-arm-O0','gcc-arm-O1', 'gcc-arm-O2', 'gcc-arm-O3', 'gcc-arm64-O0','gcc-arm64-O1', 'gcc-arm64-O2', 'gcc-arm64-O3', 'clang-x86-O0','clang-x86-O1', 'clang-x86-O2', 'clang-x86-O3', 'clang-x64-O0','clang-x64-O1', 'clang-x64-O2', 'clang-x64-O3', 'clang-arm-O0','clang-arm-O1', 'clang-arm-O2', 'clang-arm-O3', 'clang-arm64-O0','clang-arm64-O1', 'clang-arm64-O2', 'clang-arm64-O3'],dtype='object')
这个样本的源代码如下:
static int dump_headers(FILE *inp){ struct bsid sid; while(!ensure_read(&sid, inp)) { size_t s=0; dump_sid(&sid); s=(sid.Size)+(sid.dwStreamNameSize); if(skip_data(inp, s)) return -1; } return 0; }
源代码对应的gcc-x64-O0二进制代码
seg000:0000000000000000 ; File Name : \wsl\kali-linux\home\aipwn\Desktop\CodeCMR\CodeCMR\all-arch-nx\81313_1\gcc-x64-O0.nx seg000:0000000000000000 ; Format : Binary file seg000:0000000000000000 ; Base Address: 0000h Range: 0000h - 0ADAh Loaded length: 00000ADAh seg000:0000000000000000 seg000:0000000000000000 .686p seg000:0000000000000000 .mmx seg000:0000000000000000 .model flat seg000:0000000000000000 seg000:0000000000000000 ; =========================================================================== seg000:0000000000000000 seg000:0000000000000000 ; Segment type: Pure code seg000:0000000000000000 seg000 segment byte public 'CODE' use64 seg000:0000000000000000 assume cs:seg000 seg000:0000000000000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing seg000:0000000000000000 db 80h ; € seg000:0000000000000001 ; --------------------------------------------------------------------------- seg000:0000000000000001 add al, 95h ; ' seg000:0000000000000003 iret seg000:0000000000000003 ; --------------------------------------------------------------------------- seg000:0000000000000004 db 0Ah seg000:0000000000000005 align 8 seg000:0000000000000008 dq 74656E188C000000h, 6C632E786B726F77h, 69642E7365737361h seg000:0000000000000008 dq 78C946870617267h, 9468706172476944h, 28947D9481299493h seg000:0000000000000008 dq 73696C6A64611A8Ch, 5F72656E6E695F74h, 6361665F74636964h seg000:0000000000000008 dq 62088C9479726F74h, 94736E69746C6975h, 939474636964048Ch seg000:0000000000000008 dq 5F65646F6E118C94h, 6361665F74636964h, 8C08689479726F74h seg000:0000000000000008 dq 74615F6567646516h, 5F746369645F7274h, 9479726F74636166h seg000:0000000000000008 dq 646F6E5F058C0868h, 7D014B28947D9465h, 5F776172088C2894h seg000:0000000000000008 dq 17C589461746164h, 12030202E310000h, 20202002776F6C20h seg000:0000000000000008 dq 6C6C616320012020h, 75736E6524070120h, 2646165725F6572h seg000:0000000000000008 dq 747361663C090107h, 36746E695F5F223Ah, 2826202231612034h seg000:0000000000000008 dq 325F726176250C01h, 222C382E290C0230h, 32612A20454C4946h seg000:0000000000000008 dq 2E69647205012022h, 7D317B0401050238h, 20902382E3E0402h seg000:0000000000000008 dq 12009022C090120h, 502342E78616505h, 104027D367B0401h seg000:0000000000000008 dq 20393433203B2004h, 2C382E6964723D75h, 2C574F4C424C4728h
源代码对应的clang-arm-O3二进制代码
seg000:0000000000000000 ; File Name : \wsl\kali-linux\home\aipwn\Desktop\CodeCMR\CodeCMR\all-arch-nx\81313_1\clang-arm-O3.nx seg000:0000000000000000 ; Format : Binary file seg000:0000000000000000 ; Base Address: 0000h Range: 0000h - 0809h Loaded length: 00000809h seg000:0000000000000000 seg000:0000000000000000 .686p seg000:0000000000000000 .mmx seg000:0000000000000000 .model flat seg000:0000000000000000 seg000:0000000000000000 ; =========================================================================== seg000:0000000000000000 seg000:0000000000000000 ; Segment type: Pure code seg000:0000000000000000 seg000 segment byte public 'CODE' use64 seg000:0000000000000000 assume cs:seg000 seg000:0000000000000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing seg000:0000000000000000 db 80h ; € seg000:0000000000000001 db 4 seg000:0000000000000002 db 95h ; seg000:0000000000000003 dd offset byte_7FE seg000:0000000000000007 align 8 seg000:0000000000000008 dq 74656E188C000000h, 6C632E786B726F77h, 69642E7365737361h seg000:0000000000000008 dq 78C946870617267h, 9468706172476944h, 28947D9481299493h seg000:0000000000000008 dq 73696C6A64611A8Ch, 5F72656E6E695F74h, 6361665F74636964h seg000:0000000000000008 dq 62088C9479726F74h, 94736E69746C6975h, 939474636964048Ch seg000:0000000000000008 dq 5F65646F6E118C94h, 6361665F74636964h, 8C08689479726F74h seg000:0000000000000008 dq 74615F6567646516h, 5F746369645F7274h, 9479726F74636166h seg000:0000000000000008 dq 646F6E5F058C0868h, 7D014B28947D9465h, 5F776172088C2894h seg000:0000000000000008 dq 14C589461746164h, 12030202E310000h, 20202002766F6D20h seg000:0000000000000008 dq 342E307205012020h, 27D317B04010502h, 12009022C090104h seg000:0000000000000008 dq 10502342E357205h, 202004027D317B04h, 2004012020202020h seg000:0000000000000008 dq 3D7520433433203Bh, 20202020342E3072h, 2E35723D64202020h seg000:0000000000000008 dq 31202E310A040234h, 20027A6E6A200120h, 6163200120202020h seg000:0000000000000008 dq 6E65240701206C6Ch, 6165725F65727573h, 61663C0901070264h seg000:0000000000000008 dq 524F57445F3A7473h, 30250C0128262044h, 2C342E290C023078h seg000:0000000000000008 dq 12044524F57445Fh, 10502342E307205h, 2E3E04027D317B04h
gcc-x64-O0 literal features
{'c_str': [], 'c_expr': [2, 65, 61, 57, 64, 52, 65, 2, 65, 35, 65, 65, 61, 48, 57, 64, 65, 35, 65, 65, 49, 48, 57, 64, 48, 52, 65, 65, 61], 'm_int': [0, 0, 4294967295, 0, 0], 'c_state': [71, 75, 71, 72, 72, 72, 73, 71, 80, 80], 'c_int': [0, 4294967295, 0]}
gcc-x64-O0 CFG features
[(1, [[10, 56, 79, 73, 83, 74, 73, 74], [55, 80, 73, 73]]), (2, [[4, 75, 73, 78], [56, 79, 73, 83], [12, 78, 8, 78, 73, 73, 78], [44, 10, 56, 79, 73, 74, 12, 78, 8, 78, 73, 73, 73, 73, 73, 75, 80]]), (3, [[4, 75, 73, 74], [55, 80, 73, 73]]), (4, [[10, 56, 79, 73, 83, 74, 73, 74]]), (5, [[44, 74, 75, 80]]), (6, [[4, 75, 73, 74]])]
clang-arm-O3 literal features
{'c_str': [], 'c_expr': [2, 65, 65, 61, 57, 64, 52, 65, 65, 57, 64, 52, 65, 57, 64, 65, 35, 65, 65, 61, 57, 64, 52, 65, 65, 61, 61], 'm_int': [0, 0, 0, 0, 4294967295], 'c_state': [71, 72, 73, 71, 80, 75, 71, 72, 73, 71, 78, 73, 71, 80, 80], 'c_int': [0, 0, 1, -1]}
clang-arm-O3 CFG features
[(1, [[4, 74, 73, 74], [43, 56, 79, 73, 83, 74, 75, 80]]), (2, [[56, 79, 73, 83], [43, 56, 79, 73, 74, 12, 78, 78, 73, 75, 80]]), (3, [[44, 56, 79, 73, 83, 74, 75, 80]]), (4, [[4, 75, 73, 74], [55, 80, 73, 73]]), (5, [[4, 75, 73, 74]])]
下面我们来看论文的内容
二进制代码和对于的源代码
首先要面对的问题是从源代码和二进制代码中自动提取特征。除了字符串,立即数,代码里面的隐藏的语义特征很关键。
从模型上看,是把字符级别的源代码,字符串和立即数,二进制代码提取的控制流图,字符串和立即数,这三个不同的输入(语义特征、字符串特征、立即数特征)分别用模型计算得到向量,再用拼接得到代码向量。
再来看看分别处理输入的语义模型
处理源代码的模型是DPCNN,处理二进制代码的是GNN。
下图是论文的实验效果
最后是论文的链接和官方介绍:
论文链接:
https://keenlab.tencent.com/zh/whitepapers/neurips-2020-cameraready.pdf
官方介绍:
https://keenlab.tencent.com/zh/2020/11/03/neurips-2020-cameraready/
官方还出了一个IDA的插件,可以在逆向时使用,相信不久这篇论文的成果也会集成在这个工具里面,可以试用一下。
工具文档:
https://binaryai.readthedocs.io/en/stable/
往期回顾: