汇编 scanf_反汇编代码还原之特殊除法还原

本文详细探讨了汇编语言中处理除法的特殊技巧,包括数学知识的应用,如代数、分数运算,以及针对不同情况的汇编代码还原与优化,涉及到x86和x64乘法特性的分析。
摘要由CSDN通过智能技术生成

17b6790c9452d58b172572b9b55b734d.png

本文为看雪论坛精华文章

看雪论坛作者ID:TkBinary

  • 目录

  • 系列文章

  •  一. 了解数学知识

  •       1.1 简介

  •       1.2 数学知识

  •           1.2.1 数学知识之代数与解方程

  •           1.2.2 简化表达式去括号

  •           1.2.3 简化表达式之交叉相乘

  •           1.2.4 简化表达式之合并同类项

  •           1.2.5 简化表达式之分数的加法简化

  •           1.2.7 简化表达式之分数乘法

  •           1.2.6 简化表达式之分数的减法简化

  •           1.2.8 分数除法

  • 二. 除法特殊汇编

  •      2.1 特殊定式汇编

  •           2.1.1高级代码与汇编对应

  •           2.1.2 核心代码反汇编还原

  •           2.1.3 特殊汇编的除法原理

  •           2.1.4 x86乘法特性与x64乘法特性

  •           2.1.5 汇编等式还原

  •     2.2 特殊汇编M大于0x80000000的加调整

  •          2.2.1 高级代码与反汇编

  •          2.2.2 代码定式还原

  •          2.2.3代码优化原理

  •     2.3 特殊汇编大于0x80000000无调整

  •          2.3.1 高级代码与反汇编

  •          2.3.2 代码定式还原

  •          2.3.3 除法原理还原

  •     2.4 M小于0x80000000 的减调整

  •          2.4.1高级代码与反汇编

  •          2.4.2 代码公式还原

  •          2.4.3 除法优化原理

  • 三. 总结

系列文章 反汇编技术之熟悉IDA工具 https://bbs.pediy.com/thread-224499.htm
反汇编逆向技术之寻找Main入口点 https://bbs.pediy.com/thread-224500.htm
反汇编代码还原之优化方式
反汇编代码还原之加减乘
反汇编代码还原之除法为2的幂
反汇编代码还原之除法为非2的幂
一. 了解数学知识

1.1 简介

在下面会有大量的数学知识来进行讲解,当然如果你奔着如何还原,直接按照定式还原就行,不用纠结如何计算出来的。   但是你了解数学知识,从数学角度来看待优化,那么会可以了解其真正原理。本人数学也不好,但还是查阅很多资料,把基础数学 罗列出来,一来是便 于复习,二来是能看到基本的数学公式即可。

1.2 数学知识

1.2.1 数学知识之代数与解方程
方程:有一个未知数,我们来解这个未知数那么叫做解方程。   例如:
x + 3 = 64x + 5 = 17
解方程我们可以代入一个数进行去解,也可以直接做平衡解。   意思就是如果等式的左边+ 那么我们就利用减法,两边都减去这个值.。如果是x ,那么做相反运算也就是反之亦然。   解:
x + 3 = 6x +3-3= 6 - 3x = 3 4x + 5 = 174x + 5 - 5 = 17 - 54x = 124x / 4 = 12 / 4x = 3
1.2.2 简化表达式去括号
简化表达式分为移除括号,交换结合定律,合并同类项等。   移除括号,看公式:
3(5 + 2) 展开的时候计算括号的值变成 3*5 + 3*2 = 15 + 6a(b + c) = ab + ac3(x + 6) = 3x + 3*6负数乘法去括号遵循 负正得负 负负得正的规律-3(a + -6) =  -3a + -3*-6 = -3a + 18-3(a + 6) = -3a + -3*6 = -3a + -18
关于去括号的另一个特性:
3 * (2 + 4) = 3 * 63 *(2 + 4) = 3*2 + 3*4
两种方式都是可以得出结果的,一般第一种就是加这个数的和,第二种就是拆分为乘数来,计算之后再相加。   第二种用途用于不好算的数来用的。   例如:
2 * 204  直接算算不出可以简化为2* 200 + 2*4 = 408
1.2.3 简化表达式之交叉相乘
交叉相乘用于分数,可以帮助我们进行简化。   解决的是把一个分数变为表达式:

 1e8428ffc3a749808afae4d0120bb240.png

原理就是分子与分母相乘f3c4838f7f28f49f8479c0a2df077763.png 可以看到分子变了,而分母都变成了(12×3) ,所以都是除同一个数。   所以可以去掉了,变成 8 × 3 = 12 × 2。   公式记为: 26255fc83d278708bad5352cc6ffde97.png
1.2.4 简化表达式之合并同类项
如果看官方简介会看到一大堆名词解释,那么这里说一下自我的理解吧。   同类项 就是这一类属于一项,优先把他们组合起来。   例如: e1846ffdfbcaa5bc85b5992bf0a4e4b8.png 在这里有xy就是同类项,所以可以优先组合起来。   组合的时候我们可以再根据加法减法符号来组合同符合类别的。
(-xy + 5xy) + (-2xy - 4xy)+(3 - 7) == -2xy - 4也可以变成
1.2.5 简化表达式之分数的加法简化
分数加法:   分数的加法是有一条简单的规矩的,就是去分母。   如何去分母之前也有说,就是让分母一致,然后直接计算分子。   我们可以看一下上面的倒数相乘去分母,就是一个很好的例子:   c7bb046131d3148fe6b612dccca36bce.png 公式为如上,也就是交叉相乘的结果: 0e53f6e85e9765ca4f53f3e96426b371.png
1.2.6 简化表达式之分数的减法简化
分数减法同加法一样,只不管变成相减了: c47b0b5ae32ae3d5feaa0549e488eb2a.png
1.2.7 简化表达式之分数乘法
分数乘法   分数乘法简化还是按照上乘上下乘下原则: a4ab37ccdfeb290371715426b8d643bc.png
1.2.8分数除法
分数除法要转变为分数乘法,具体原则就是分数的倒数来进行相乘。 8f63cd20b2886734050878e1f9224747.png 其余按照分数乘法来做。
二. 除法特殊汇编

2.1 特殊定式汇编

2.1.1高级代码与汇编对应
高级代码:
int main(int argc, char* argv[]){    /*    除法    */     unsigned int NumberOne = 0;     unsigned int NumberTwo = 0;     scanf("%u",&NumberOne);     scanf("%u",&NumberTwo);     unsigned int Count1 = NumberOne / -6;     unsigned int Count2 = NumberTwo / 7;    printf("%d%d",Count2,Count1);    system("pause");    return 0;}
一个是无符号/-6 一个是/正数7。   看下汇编:
.text:00401000.text:00401000.text:00401000 ; int __cdecl main(int argc, const char **argv, const char **envp).text:00401000 _main           proc near               ; CODE XREF: start+AF↓p.text:00401000.text:00401000 var_8           = dword ptr -8.text:00401000 var_4           = dword ptr -4.text:00401000 argc            = dword ptr  4.text:00401000 argv            = dword ptr  8.text:00401000 envp            = dword ptr  0Ch.text:00401000.text:00401000                 sub     esp, 8.text:00401003                 xor     eax, eax.text:00401005                 mov     [esp+8+var_8], eax.text:00401009                 mov     [esp+8+var_4], eax.text:0040100D                 lea     eax, [esp+8+var_8].text:00401011                 push    eax.text:00401012                 push    offset aU       ; "%u".text:00401017                 call    _scanf.text:0040101C                 lea     ecx, [esp+10h+var_4].text:00401020                 push    ecx.text:00401021                 push    offset aU       ; "%u".text:00401026                 call    _scanf.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 7.text:00401034                 mul     ecx.text:00401036                 sub     ecx, edx.text:00401038                 mov     eax, 24924925h.text:0040103D                 shr     ecx, 1.text:0040103F                 add     ecx, edx.text:00401041                 shr     ecx, 1Fh.text:00401044                 push    ecx.text:00401045                 mov     ecx, [esp+1Ch+var_4].text:00401049                 mul     ecx.text:0040104B                 sub     ecx, edx.text:0040104D                 shr     ecx, 1.text:0040104F                 add     ecx, edx.text:00401051                 shr     ecx, 2.text:00401054                 push    ecx.text:00401055                 push    offset aDD      ; "%d%d".text:0040105A                 call    _printf.text:0040105F                 push    offset aPause   ; "pause".text:00401064                 call    _system.text:00401069                 xor     eax, eax.text:0040106B                 add     esp, 28h.text:0040106E                 retn.text:0040
2.1.2 核心代码反汇编还原
我们去掉流水线优化后的核心反汇编如下:
.text:00401000.text:00401000.text:00401000 ; int __cdecl main(int argc, const char **argv, const char **envp).text:00401000 _main           proc near               ; CODE XREF: start+AF↓p.text:00401000.text:00401000 var_8           = dword ptr -8.text:00401000 var_4           = dword ptr -4.text:00401000 argc            = dword ptr  4.text:00401000 argv            = dword ptr  8.text:00401000 envp            = dword ptr  0Ch.text:00401000 .text:00401003                 xor     eax, eax.text:00401005                 mov     [esp+8+var_8], eax.text:00401009                 mov     [esp+8+var_4], eax核心位置 /-6.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 7.text:00401034                 mul     ecx.text:00401036                 sub     ecx, edx.text:0040103D                 shr     ecx, 1.text:0040103F                 add     ecx, edx.text:00401041                 shr     ecx, 1Fh.text:00401044                 push    ecx核心位置/7.text:00401038                 mov     eax, 24924925h.text:00401045                 mov     ecx, [esp+1Ch+var_4].text:00401049                 mul     ecx.text:0040104B                 sub     ecx, edx.text:0040104D                 shr     ecx, 1.text:0040104F                 add     ecx, edx.text:00401051                 shr     ecx, 2.text:00401054                 push    ecx
观看代码定式,我们发现了一个特点:核心汇编代码都是乘、减、移、加、移的指令。
.text:00401038                 mov     eax, 24924925h.text:00401045                 mov     ecx, [esp+1Ch+var_4].text:00401049                 mul     ecx.text:0040104B                 sub     ecx, edx.text:0040104D                 shr     ecx, 1.text:0040104F                 add     ecx, edx.text:00401051                 shr     ecx, 2.text:00401054                 push    ecx
如果你想要还原,记住代码定式:
.text:00401038                 mov     eax, M.text:00401045                 mov     ecx, 被除数.text:00401049                 mul     ecx.text:0040104B                 sub     ecx, edx.text:0040104D                 shr     ecx, n.text:0040104F                 add     ecx, edx.text:00401051                 shr     ecx, n.text:00401054                 push    ecx
利用除法转变为乘法的特性,我们首先统计n值,然后使用2的幂加上n值, 一般是2^(32 + n)。   注意这里是幂值相加。   如下:   0816cc8d36e9a2d7c00ea5c77418a26f.png 然后统计M值。   这里的代码还原的公式为:

67aafb17891efaf2e92facc37ac96c01.png

正数的还原手法 比如我们要还原/7,我们可以代入公式:   设M = 24924925h 10进制 = 613566757   设n值 = 3 进行幂相加后得出 2^35   代入公式之后计算的结果向上取整: 99ed9c20709196c49ab54b7a6adc0e81.png 得出结果为7,这个就是我们求的被除数,所以这一整段代码我们可以还原为:var_4 / 7。 负数的还原手法 如果是负数一样代入公式,比如这里是/-6:   M = 7   n = 1F + 1 = 32   代入公式得:

a925ec0430cd03e5bba10159cea87ef3.png

很明显这是一个很大的数,这个数放到计算器中可以看到是一个负数: 52633f95018a7da016486716f2d121ac.png 我们看16进制就可以看出这个是个负数,我们对其取反,然后转变为DWORD即可。

ddb1eb39029340b43dda5c7feb0f9252.png

2.1.3 特殊汇编的除法原理
还记得我们上一讲的除法转变为乘法的例子吧。   简单例子如下: 137e1681efcb7a4cec6180fb170f0826.png 那么这里其实本质还是用这个除法转变为乘法的公式,只不过有些许不同。   不同点在于C计算位置,也就是计算M数的时候。如果n的取值大于32,那么其结果会超过4个字节整数的表达范围,所以要进行调整。   调整为我减去2^32次方,然后最后的时候再加上。   比如下: e13b13eff0a92de3ff87b8f2396578a4.png 那么我们的除法就会随之改变,剩下的就是求出M怎么得出的。   在这里我们看下汇编表达形式,并且列出与之对应表达式,但是我们先看一下乘法的特性。
2.1.4 x86乘法特性与x64乘法特性
x86乘法特性 在x86下,乘法的乘积放在edx.eax中,但是这不是绝对。看如下: c50d07cf849e55282ec5ed0611c72176.png 举例:
mov al,5hmov bl,10hmul bl           //ax == 0050,CF = 0

d9771a6130435ed8f0f69af23af4439d.png

与之同理:
.dataval1 WORD 2000hval2 WORD 0l00h.codemov ax, val1           ; AX = 2000hmul val2               ; DX:AX = 00200000h, CF = 1

612a479b8df4fa2326250d058a4a1bfa.png

4字节计算被乘数是4个字节:
mov eax, 12345hmov ebx, 1000hmul ebx                   ; EDX:EAX = 0000000012345000h, CF = 0
ca1fdef3374bd00ebb66ffc77f33f16b.png x64下的乘法特性 64位模式下 ,MUL 指令可以使用64位操作数一个64位寄存器或内存操作数与RAX相乘,产生的128位乘积存放到RDX:RAX寄存器中。 下例中,RAX 乘以 2,就是将 RAX 中的每一位都左移一位。RAX 的最高位溢出到 RDX 寄存器,使得 RDX 的值为 0000 0000 0000 0001h:
.datamultiplier QWORD 10h.codemov rax, OAABBBBCCCCDDDDhmul multiplier       ; RDX:RAX = 00000000000000000AABBBBCCCCDDDDOh
2.1.5 汇编等式还原
了解了乘法原理我们来看等式,根据我们的汇编产生的等式:
.text:00401038                 mov     eax, 24924925h.text:00401045                 mov     ecx, [esp+1Ch+var_4].text:00401049                 mul     ecxeax = Mecx = 被除数M * ecx 结果放在 edx:eax中 .text:0040104B                 sub     ecx, edx此条代码是让被除数 - M*ecx的高32位乘积.等价于 ecx - (M * ecx)/2^32 .text:0040104D                 shr     ecx, 1然后整体又/2的一次方(ecx - (M * ecx)/2^32)/2^1.text:0040104F                 add     ecx, edx最后又加上乘积的高位((ecx - (M * ecx)/2^32)/2) + (M * ecx)/2^32 .text:00401051                 shr     ecx, 2最后整体又/2的2次方(((ecx - (M * ecx)/2^32)/2) + (M * ecx)/2^32)/2^2.text:00401054                 push    ecx  最后使用乘积高位
最终我们以图示的方式来列出公式: f0d8880a29eb47083adea937db83fcd8.png 然后我们化简。   首先是第一段化简,也可以称作是简化,如果不明白看下上面的数学知识补充: d808ea5449e8f7f2be19e3c3317182b3.png 最后得出的公式,我们直接求解即可。   2^35 / (2^32 + M) 就得出了最终结果。   比如我们的 /7 我们代入公式:
2^35 / (2^32 + 24924925h) === 6.99999 向上取整 = 7

2.2 特殊汇编M大于0x80000000的加调整

2.2.1 高级代码与反汇编
int main(int argc, char* argv[]){    /*    除法    */      int NumberOne = 0;      int NumberTwo = 0;       scanf("%u",&NumberOne);    scanf("%u",&NumberTwo);      int Count1 = NumberOne / 7;       printf("%d%d%d",Count1);    system("pause");     return 0;}
汇编对应代码:
.text:00401000 ; int __cdecl main(int argc, const char **argv, const char **envp).text:00401000 _main           proc near               ; CODE XREF: start+AF↓p.text:00401000.text:00401000 var_8           = dword ptr -8.text:00401000 var_4           = dword ptr -4.text:00401000 argc            = dword ptr  4.text:00401000 argv            = dword ptr  8.text:00401000 envp            = dword ptr  0Ch.text:00401000.text:00401000                 sub     esp, 8.text:00401003                 xor     eax, eax.text:00401005                 mov     [esp+8+var_8], eax.text:00401009                 mov     [esp+8+var_4], eax.text:0040100D                 lea     eax, [esp+8+var_8].text:00401011                 push    eax.text:00401012                 push    offset aU       ; "%u".text:00401017                 call    _scanf.text:0040101C                 lea     ecx, [esp+10h+var_4].text:00401020                 push    ecx.text:00401021                 push    offset aU       ; "%u".text:00401026                 call    _scanf.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 92492493h.text:00401034                 imul    ecx.text:00401036                 add     edx, ecx.text:00401038                 sar     edx, 2.text:0040103B                 mov     eax, edx.text:0040103D                 shr     eax, 1Fh.text:00401040                 add     edx, eax.text:00401042                 push    edx.text:00401043                 push    offset aDDD     ; "%d%d%d".text:00401048                 call    _printf.text:0040104D                 push    offset aPause   ; "pause".text:00401052                 call    _system.text:00401057                 xor     eax, eax.text:00401059                 add     esp, 24h.text:0040105C                 retn.text:0040105C _main           endp
提取出核心汇编:
.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 92492493h.text:00401034                 imul    ecx.text:00401036                 add     edx, ecx.text:00401038                 sar     edx, 2.text:0040103B                 mov     eax, edx.text:0040103D                 shr     eax, 1Fh.text:00401040                 add     edx, eax.text:00401042                 push    edx
2.2.2 代码定式还原
观看上面代码.发现跟我们除法转化为乘法的代码定式很像,唯一不同的就是在使用 imul 指令之后,后面不是移位而是紧接着是一个add指令。   其实这里的代码跟我们的特殊汇编第一种很相似,这里的M数也很大,原因是除法转换为乘法的时候做了调整,加了2^32次方。 这个定式等价于除法转化为乘法的定式。   直接使用这个定式进行还原即可:
2^34 / 2454267027 = 6.999... = 7
除法转化为乘法的代码定式为:   82b60d68f1cb4f3a0144b2ac93cd3ef5.png 解方程得: f74876269bfbeb8f9d98dc49b77f03ae.png
2.2.3代码优化原理
编译器再计算M数的时候(2^n/b)是以无符号数来进行计算的,而代入除法转变为乘法的代码中,是以有符号进行处理的,有符号的最高位是代表符号位。   而无符号的最高位是数据位,所以如果你以无符号来进行计算,那么结果就会出错,所以我们计算机中如果(2^n/b)计算出的M数大于0x80000000。   最高位为1也就是负数的表现形式,那么实际参与除法转变为乘法的过程是以补码来计算的,结果是以 7115d1f7d02901f33106a276670a77c0.png 来进行计算的,所以我们的除法转变为乘法的公式又变了。   变成了: d657507c73aaf11fce99c9b4b06d37b0.png 这里的括号是求补码的意思,计算机中 2^n / b - 2^32次方是可以计算出来的。   所以根据我们的代码定式列出方程式:
.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 92492493h.text:00401034                 imul    ecx.text:00401036                 add     edx, ecx.text:00401038                 sar     edx, 2.text:0040103B                 mov     eax, edx.text:0040103D                 shr     eax, 1Fh.text:00401040                 add     edx, eax.text:00401042                 push    edx
在加法这里,直接使用edx相加。而EXE是M与被除数计算出来,是乘积的高位,所以这里的edx等价于是: bee4c5ccde7dba47e7135ad04eefb2f7.png 我们直接列出公式: 9bb14b99f4fface78a43e807e73788ac.png 直接进行代码公式优化即可: 08b27b0baa3f9cb3c34dff83e576ef1c.png 这个公式等价于除法转变为乘法的公式,所以直接使用公式还原即可。

2.3 特殊汇编大于0x80000000无调整

当除数为负数且无调整的时候会出现这样的问题新的除法调整。
2.3.1 高级代码与反汇编
int main(int argc, char* argv[]){    /*    除法    */      int NumberOne = 0;      int NumberTwo = 0;    scanf("%u",&NumberOne);    scanf("%u",&NumberTwo);    int Count1 = NumberOne / -5;    printf("%d",Count1);    system("pause");     return 0;}
核心汇编:
.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 99999999h            大于0x8..没有进行调整.text:00401034                 imul    ecx.text:00401036                 sar     edx, 1.text:00401038                 mov     eax, edx.text:0040103A                 shr     eax, 1Fh.text:0040103D                 add     edx, eax.text:0040103F                 push edx
2.3.2 代码定式还原
遇到上述指令,直接使用代码定式还原: 5182b7569868cecf31aed5a526cf08d4.png 这里我们已知M跟n值,直接代入公式即可: 27186e4650c24461ced857ea2a9ae98b.png 结果向上取整,但是我们结果要判别为负。
2.3.3 除法原理还原
首先我们先看一下除法转变为乘法的公式: 3e4403532c2a74319719fa1f89560761.png 47f2989fc3d97b8bd8e3c81cd10c289e.png 如果我们b为正数的时候,那么公式就是使用上面的公式。如果为负数那么除法公式就变化了,变成了负数的方式求结果了。   如下:

9ad0bc497dcfc27e9086a8ee5195d72e.png

求 -C: 7bf56c0402fa0dc224f92170455c5fdb.png 那么最终如果我们要求b(除数) 就是 2^n /(2^32 - M) 即可。

2.4 M小于0x80000000 的减调整

减调整对于我们特殊的定式汇编我们算的是加调整,M值是小于0x80000000 而且有add调整,说明是一个正数。   如果小于还是进行减调整,那么我们要还原的除数还是为负数。
2.4.1高级代码与反汇编
看下高级代码:
int main(int argc, char* argv[]){    /*    除法    */      int NumberOne = 0;      int NumberTwo = 0;       scanf("%u",&NumberOne);    scanf("%u",&NumberTwo);      int Count1 = NumberOne / -7;       printf("%d",Count1);    system("pause");     return 0;}
核心反汇编:
.text:0040102B                 mov     ecx, [esp+18h+var_8].text:0040102F                 mov     eax, 6DB6DB6Dh.text:00401034                 imul    ecx.text:00401036                 sub     edx, ecx                                减调整.text:00401038                 sar     edx, 2.text:0040103B                 mov     eax, edx.text:0040103D                 shr     eax, 1Fh.text:00401040                 add     edx, eax.text:00401042                 push    edx
2.4.2 代码公式还原
如果想要计算出上方的定式,那么我们还是使用 00fe1103a9d31a4a1b1c04ae12a60692.png 进行还原即可。   代入公式得:
2^34 / (2^32 - 6DB6DB6Dh) = 6.99999...
结果向上取整,得出7,但是是负数所以得出是-7。
2.4.3 除法优化原理
跟我们除数为 +7的代码公式相似。(2.2小结,M大于0x8000000) 只不过除数变成负数,.所以要对M数进行取负计算。   公式如下: 00b226f8e3b45e5d3553378676e1682a.png 上面的公式是有符号为正数的公式,此时我们对我们的M取负数即可。   设C为如下公式:

9a25d304f3459054f04197e287901561.png

最终求解即可。   使用以下进行还原即可:

00fe1103a9d31a4a1b1c04ae12a60692.png

三. 总结 1. M小于0x80000000 如果M大于0x8... 且有加调整, 那么除数为正数,使用 b = 2^n / b 还原即可。 如果M大于0x8 且没有调整, 那么除数为负数,使用 b = 2^n /(2^32 - M) 还原即可。 2. M大于0x80000000 如果有减调整,.那么除数为负数,使用 b = 2^n/(2^32-M) 即可。 如果加调整,且满足乘减移加移,使用 b = 2^n/(2^32+M) 即可。 除法的优化与还原资料,参考自恩师钱林松出版的 《C++反汇编与逆向分析技术揭秘C+》 。在此前提上加了自己的一些理解,以及定式还原的方式。   最后感谢一下编程技术版主KevinsBobo本书的公式资料。在我写的时候有些许不理解,最后请教编程技术版,然后熬夜做公式做还原得出的。   还是那句话,高手复习,新手学习。

c5817869e4f04acaf5d50bf974b0b4df.gif

- End -

3ac171c9fd858a17409a50e9901e4f23.png

看雪ID:TkBinary

https://bbs.pediy.com/user-home-723188.htm

  *本文由看雪论坛 TkBinary 原创,转载请注明来自看雪社区。

292b5802e430da992f13dd32fbda7ffe.png

2.5折优惠票数量有限,先到先得哦! 077b8a03dd1d374ebee045be8997a2b0.png

推荐文章++++

61c1a57a036b376352d96f39bf701674.png

* 黑白鉴定入门之一款后门的分析思路

* 双向进攻:分析tcpdump DOS漏洞成因

* PWN:fastbin attack学习

* 反汇编代码还原之除数为非2的幂

* 格式化字符串漏洞解析

ebf73763bf0f441f092aa6ebd48b65f4.png 公众号ID:ikanxue 官方微博:看雪安全 商务合作:wsc@kanxue.com d54ecbef-e130-eb11-8da9-e4434bdf6706.svg

求分享

d74ecbef-e130-eb11-8da9-e4434bdf6706.svg

求点赞

4a3b7bc51d55fad5799c918089dbe5d9.gif

求在看

40b302c7d0e26faa24a107ab7539ba55.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值