roger 发表于 2020-9-9 21:21:47

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

目录
[*] 代码还原反汇编之除法除数为非2的幂
[*]               系列文章
[*]         一丶数学知识补充
[*]               1.1 简介
[*]               1.2 分数
[*]                         1.2.1分数加法
[*]                         1.2.1分数乘法
[*]         二丶除法优化之有符号非2的幂优化
[*]               2.1高级代码与反汇编
[*]               2.2 除法非2的幂还原
[*]               2.3 除数为非2的幂的优化与原理
[*]               2.4 总结除法还原公式
[*]         三丶除法优化之无符号非2的幂优化
[*]               3.1 无符号非2的幂除数为正代码反汇编还原
[*]               3.2 无符号非2的幂除数为负数反汇编代码还原
[*]               3.3 特殊汇编
[*]         四丶为什么学习除法优化
[*]               4.1 为什么学习除法优化
[*]         五丶高级Vs编译器与linux下的gcc优化
[*]               5.1 vs2019 x86 有符号非2的幂优化
[*]               5.2 vs2019 x64有符号非2的幂优化
[*]               5.3 linux gcc x86 有符号非2的幂
[*]               5.4 其它同理自己建立项目研究
代码还原反汇编之除法除数为非2的幂系列文章  反汇编技术之熟悉IDA工具
  反汇编逆向技术之寻找Main入口点
  反汇编代码还原之优化方式
  反汇编代码还原之加减乘
  反汇编代码还原之除法为2的幂
一丶数学知识补充1.1 简介  ​    除法在非2的幂优化上,采用的是除法转变为乘法 的形式. 在学习这方面知识的时候我们先了解下简单的数学知识
  也有助于我们能看懂公式
1.2 分数1.2.1分数加法
[*]  分数加法
  相同分母加法 分子想加 分母不变 例如下

  不同分母想加 如果是不同分母想加你就要进行寻找最小公分母
  公分母指的是. 当两个或者以上的分数有相同的分母 那么他们便是公分母 注意这里是公分母.而不是最小公分母 最小公分母指的是两个分数以上,最小的公分母

[*]  最小公分母的寻找
  最小公分母我们可以列出 分母的倍数 如果有两个分数那么都列出分母的倍数.找出相同的倍数.然后让其等价即可.
  例如:
  列出3的倍数: 3 6 9 12 15 .....
  列出6的倍数: 6 12 18 24 ....
  我们发现最小公倍数都是6. 所以我们的分子分母都*2转为为相同分母然后进行想加即可

1.2.1分数乘法
[*]  分数乘法
**分数*分数 是分子 * 分子 分母 * 分母**  
  如下:
  ​   
  口诀: 乘分数 没难度 上乘上 下乘下 再约分

[*]  整数相乘
  如果一个整数 * 一个分数.那么这个分数就可以看做是分子,而分母就是1
  例子:
  至于约分.可以寻找最小公因数.跟公倍数相反.公倍数是找出相乘 公因数就是找出可以分子/分母的数. 都去除同一个数
二丶除法优化之有符号非2的幂优化2.1高级代码与反汇编int main(int argc, char* argv[])  {
  /*
  除法
  */
  int NumberOne = 0;
  int NumberTwo = 0;
  scanf("%d",&NumberOne);
  scanf("%d",&NumberTwo);
  int Count1 = NumberOne / 3;
  int Count2 = NumberTwo / 5;
  int Count3 = NumberTwo / 6;
  int Count4 = NumberTwo / 9;
  printf("%d%d%d%d%d",Count4,Count3,Count2,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 ptr4
  .text:00401000 argv            = dword ptr8
  .text:00401000 envp            = dword ptr0Ch
  .text:00401000
  .text:00401000               sub   esp, 8
  .text:00401003               xor   eax, eax
  .text:00401005               mov   , eax
  .text:00401009               mov   , eax
  .text:0040100D               lea   eax,
  .text:00401011               push    eax
  .text:00401012               push    offset aD       ; "%d"
  .text:00401017               call    _scanf
  .text:0040101C               lea   ecx,
  .text:00401020               push    ecx
  .text:00401021               push    offset aD       ; "%d"
  .text:00401026               call    _scanf
  //第一段
  .text:0040102B               mov   ecx,
  .text:0040102F               mov   eax, 55555556h
  .text:00401034               imul    ecx
  .text:0040103A               mov   eax, edx
  .text:0040103C               shr   eax, 1Fh
  .text:0040103F               add   edx, eax
  //第二段
  .text:00401036               mov   ecx,
  .text:00401041               mov   eax, 66666667h
  .text:00401047               imul    ecx
  .text:00401049               sar   edx, 1
  .text:0040104B               mov   eax, edx
  .text:0040104D               shr   eax, 1Fh
  .text:00401050               add   edx, eax
  .text:00401057               push    edx                //这里原先是流水线优化给提到上边来了
  //第三段
  .text:00401052               mov   eax, 2AAAAAABh
  .text:00401058               imul    ecx
  .text:0040105A               mov   eax, edx
  .text:0040105C               shr   eax, 1Fh
  .text:0040105F               add   edx, eax
  .text:00401066               push    edx                //同上流水线优化
  //第四段
  .text:00401061               mov   eax, 38E38E39h
  .text:00401067               imul    ecx
  .text:00401069               sar   edx, 1
  .text:0040106B               mov   ecx, edx
  .text:0040106D               shr   ecx, 1Fh
  .text:00401070               add   edx, ecx
  .text:00401072               push    edx
  .text:00401073               push    offset aDDDDD   ; "%d%d%d%d%d"
  .text:00401078               call    _printf
  .text:0040107D               push    offset aPause   ; "pause"
  .text:00401082               call    _system
  .text:00401087               xor   eax, eax
  .text:00401089               add   esp, 30h
  .text:0040108C               retn
  .text:0040108C _main         endp
  
2.2 除法非2的幂还原  ​    乍一看上面汇编代码.除法怎么变为了这样.为什么又有乘法又有除法.还有调整等. 那么这里就着重讲解一下.
  如果想要直接还原.那么我们把代码定式提取出来 直接进行还原

[*]  代码定式
mov   ecx, 被除数  mov   eax, M值
  imul    ecx
  sar   edx, n
  mov   eax, edx
  shr   eax, 1Fh
  add   edx, eax
  push    edx
  
  根据汇编我们只需要看三个点即可. 并且得出三个点的公式得原理
  其中M是编译器计算出来了. ecx是被除数. 这里sar n值.直接操作的是edx. 这里其实是除法转变为了乘法 而如果除法转变为乘法 那么在32位年代下.两个数相乘 32的值是不会放下的. 所以我们这里其实使用的是 edx,eax 来代表乘法的结果 然后我们直接操作了乘积的高位 这里右移1 等价于是 除以
  那么我们还原的时候直接记住死公式就可以.
  直接统计n的取值. 然后用 2的32次方 + n即可. 因为乘积的低位时代表2^32次方.这里直接是对乘积高位做操作.所以我们需要加上低位的32次方的值
  例子还原
.text:0040102B               mov   ecx,   .text:0040102F               mov   eax, 55555556h
  .text:00401034               imul    ecx
  .text:0040103A               mov   eax, edx                //这里直接使用的是edx.而没有对edx做修改.所以我们的n值就是0
  .text:0040103C               shr   eax, 1Fh
  .text:0040103F               add   edx, eax
  
  我们套用公式
  2.99直接向上取整 = 3. 所以这里我们就寻得被除数为3
2.3 除数为非2的幂的优化与原理  首先先看我们的汇编
.text:00401061               mov   eax, 38E38E39h  .text:00401067               imul    ecx
  .text:00401069               sar   edx, 1
  .text:0040106B               mov   ecx, edx
  .text:0040106D               shr   ecx, 1Fh
  .text:00401070               add   edx, ecx
  .text:00401072               push    edx
  
  这里我们汇编分为两部分.上边是可以直接套用公式还原. 而下方其实是获取符号位.调整一下符号位.
  shr 逻辑右移. 最高位以0填充. 右移31(1F)位 取得符号位 然后这里有一个加法.其实这个加法也是套路.跟我们之前讲解的无分支优化差不多. 如果结果是正数. 那么 add edx,eax 就是加0 等于什么都不干. 如果是结果是负数 那么我们就需要除法的商做调整.做加1调整.

[*]  除法转化为乘法的原理
  如果想要了解为什么非2的幂代码会变成上面的代码.那么我们就要理解下原理
  设 a = 被除数b = 除数(是一个常量值)
  那么就会有以下公式
  这个就是我们上面所了解的分数相关知识.
  看最后的公式
  其中 2n/b这个是可以在编译期中计算出来的. VC++6.0 或者VS2019 在编译 期间n的取值是大于32的.所以是可以算出来的.
  所以我们的公式可以变为如下 在这里我们把编译器可以计算出来的值记做C. 那么可以得出以下公式
  最终简化为就是(a * c) >> n 而反过头来看我们的汇编代码
.text:00401061               mov   eax, 38E38E39h  .text:00401067               imul    ecx
  .text:00401069               sar   edx, 1
  
  列出公式
  ecx = 被除数
  eax= M等价于 2n/b的值.
  ecx eax / 2^33   这条公式就正好对应着我们除法转变为乘法的原理 和我们上面的公式一样.(a c) >> n
  所以我们解方程即可.2^n / b = M值.那么 2^n / M= bb就是我们的要求的除数. 所以得出我们的除数
  除法还原公式为:
2.4 总结除法还原公式
[*]  除法的还原公式
  这里的C其实就是2^n/b 在汇编中我们也设为M.所以也可以写为如下

[*]  除法转变为乘法的公式
  转变为如下
  继续转变
  最终转变

  对于上面我们记住代码定式也可以进行还原.当然熟悉除法转变为乘法的原理更好.
  高级代码看其特征我们发现其实是一样的. 都可以使用 除法转乘法的公式来进行还原
  除法还原公式其实就是解方程了.解开就可以得到被除数
三丶除法优化之无符号非2的幂优化  高级代码
int main(int argc, char* argv[])  {
  /*
  除法
  */
  unsigned int NumberOne = 0;
  unsigned int NumberTwo = 0;
  scanf("%u",&NumberOne);
  scanf("%u",&NumberTwo);
  unsigned int Count1 = NumberOne / 3;
  unsigned int Count2 = NumberTwo / 5;
  unsigned int Count3 = NumberTwo / 6;
  unsigned int Count4 = NumberTwo / 9;
  printf("%d%d%d%d%d",Count4,Count3,Count2,Count1);
  system("pause");
  return 0;
  }
  
  汇编代码
.text:00401005               mov   , eax  .text:00401009               mov   , eax
  .text:0040102B               mov   eax, 2863311531
  .text:00401030               mov   ecx,
  .text:00401034               mul   
  .text:00401038               shr   edx, 1
  .text:0040103A               mov   eax, 3435973837
  .text:0040103F               push    edx
  .text:00401040               mul   ecx
  .text:00401042               shr   edx, 2
  .text:00401045               mov   eax, 0AAAAAAABh
  .text:0040104A               push    edx
  .text:0040104B               mul   ecx
  .text:0040104D               shr   edx, 2
  .text:00401050               mov   eax, 38E38E39h
  .text:00401055               push    edx
  .text:00401056               mul   ecx
  .text:00401058               shr   edx, 1
  .text:0040105A               push    edx
  
3.1 无符号非2的幂除数为正代码反汇编还原  看如上代码.根据除法转为乘法公式 (a * b) >> n .我们可以求出
  2^n / b = M2^n/M = b(除数常量)
  这里只不过是换成了无符号而已.
  还原公式还是同上
  如:
.text:0040102B               mov   eax, 2863311531  .text:00401030               mov   ecx,
  .text:00401034               mul   
  .text:00401038               shr   edx, 1
  
  取N 值 = 1 取M值 = 2863311531(注意这里IDA我按了下H转为10进制来查看.这样方便我们用科学计算器来进行运算)
  操作的是edx.所以
被除数 = 2^33  除数 = M
  求除数公式 =2^n/M = b
  代入公式
  2^33 / 2863311531 = 2.999999999 向上取整 = 3 所以得出这里的除数为3. ecx = var4
  所以这里反汇编为高级代码为 var_4 / 3
  
3.2 无符号非2的幂除数为负数反汇编代码还原  高级代码如下
int main(int argc, char* argv[])  {
  /*
  除法
  */
  unsigned int NumberOne = 0;
  unsigned int NumberTwo = 0;
  scanf("%u",&NumberOne);
  scanf("%u",&NumberTwo);
  unsigned int Count1 = NumberOne / -3;
  unsigned int Count2 = NumberTwo / -5;
  unsigned int Count3 = NumberTwo / -6;
  unsigned int Count4 = NumberTwo / -9;
  printf("%d%d%d%d%d",Count4,Count3,Count2,Count1);
  system("pause");
  return 0;
  }
  
  核心代码反汇编 代码段
.text:00401005               mov   , eax  .text:00401009               mov   , eax
  /-3
  .text:0040102B               mov   eax, 40000001h
  .text:00401030               mov   ecx,
  .text:00401034               mul   
  .text:00401038               shr   edx, 1Eh
  .text:00401040               push    edx
  /-5
  .text:0040103B               mov   eax, 80000003h
  .text:00401041               mul   ecx
  .text:00401043               shr   edx, 1Fh
  .text:0040104B               push    edx
  /-6
  .text:00401046               mov   eax, 7
  .text:0040104C               mul   ecx
  .text:0040104E               mov   eax, ecx
  .text:00401050               sub   eax, edx
  .text:00401052               shr   eax, 1
  .text:00401054               add   eax, edx
  .text:00401056               shr   eax, 1Fh
  .text:00401059               push    eax
  /-9
  .text:0040105A               mov   eax, 80000005h
  .text:0040105F               mul   ecx
  .text:00401061               shr   edx, 1Fh
  .text:00401064               push    edx
  

[*]  代码定式
  根据上面反汇编代码.我们看到三个地方 有我们的 疑似 (a * c) >> n的代码
  也就是除法转变为乘法的公式
  我们随便取出一处代入公式进行还原
  设 M = 40000001h   =10进制的 1073741825
  设 n = 1E                  = 10进制的 30
  那么代入我们的还原公式为:

  以计算器的科学计算计算出的数值是4294967292(10进制)
  那么我们将这个数复制到以程序员计算的计算器中.(复制到Dec 10进制输入) 可以看到是一个负数
  注意输入的时候以QWORD输入.然后再点击一下变成DWORD则可以看到表达为-4
  此时直接对其NOT取反则可以得到原始的被除数. 但是这个被除数常量是负数
  你也可以让此值做+1调整 变为4294967293 那么就得出了数直接就是-3 可以很明确的知道我们的被除数是-3
3.3 特殊汇编  看到上面有一段代码.我们特别不理解 为什么/-6汇编变了
  这些后面有专题转么讲解特殊的怎么还原
  现在可以看一下我算的
  2^64 / 4,294,967,302 = 0x100000006最高位为符号位 代表这是个负数也就是-6
  如果根据定式还原得出的结果为 0xFFFFFFF9 然后对其取反得到6
  但是也有代码定式
mov regA,  mov reg,M
  mul regA
  sub regA,edx
  shr regA,n
  add regA,edx
  shr regA,(n-1)
  
  观看代码定式可以得出
  乘减移加移
  这种先使用定式还原
  这里取出两个n值. 1+31 = 32所以n值为32
  代入公式得
  2^64 / 4,294,967,303 = 0XFFFFFFF9
  关于特殊汇编在下一篇应该会详细讲解.
四丶为什么学习除法优化4.1 为什么学习除法优化  ​    还是那句话为什么学习除法优化. 好就以我们上面的例子为例.那么使用IDA F5查看
  请问看到这种代码你怕了吗. 直接反汇编可以得出这一段代码我是干啥.用IDA反汇编就会得出 右移等等.在我们看来就是硬汇编
  也就是硬着头皮还原的.所以说这就是我们学习的意义所在 当然F5还是很强大的.但是我们学会了能更好的帮助我们进行反汇编,更好的通过反汇编从而还原为高级代码
五丶高级Vs编译器与linux下的gcc优化  其实还是老生常谈.拿高版本与低版本做个对比.看看优化方式是否发生了改变.
5.1 vs2019 x86 有符号非2的幂优化  高级代码
int main(int argc, char* argv[])  {
  /*
  除法
  */
  int NumberOne = 0;
  int NumberTwo = 0;
  scanf("%d",&NumberOne);
  scanf("%d",&NumberTwo);
  int Count1 = NumberOne / 3;
  int Count2 = NumberTwo / 5;
  int Count3 = NumberTwo / 6;
  int Count4 = NumberTwo / 9;
  printf("%d%d%d%d%d",Count4,Count3,Count2,Count1);
  system("pause");
  return 0;
  }
  
  汇编
.text:00401080               push    ebp  .text:00401081               mov   ebp, esp
  .text:00401083               sub   esp, 8
  .text:00401086               lea   eax,
  .text:00401089               mov   , 0
  .text:00401090               push    eax
  .text:00401091               push    offset unk_41ECDC
  .text:00401096               mov   , 0
  .text:0040109D               call    sub_401050
  .text:004010A2               lea   eax,
  .text:004010A5               push    eax
  .text:004010A6               push    offset unk_41ECDC
  .text:004010AB               call    sub_401050
  .text:004010B0               mov   ecx,
  .text:004010B3               mov   eax, 55555556h
  .text:004010B8               imul   
  .text:004010BB               mov   eax, edx
  .text:004010BD               shr   eax, 1Fh
  .text:004010C0               add   eax, edx
  .text:004010C2               push    eax
  .text:004010C3               mov   eax, 66666667h
  .text:004010C8               imul    ecx
  .text:004010CA               sar   edx, 1
  .text:004010CC               mov   eax, edx
  .text:004010CE               shr   eax, 1Fh
  .text:004010D1               add   eax, edx
  .text:004010D3               push    eax
  .text:004010D4               mov   eax, 2AAAAAABh
  .text:004010D9               imul    ecx
  .text:004010DB               mov   eax, edx
  .text:004010DD               shr   eax, 1Fh
  .text:004010E0               add   eax, edx
  .text:004010E2               push    eax
  .text:004010E3               mov   eax, 38E38E39h
  .text:004010E8               imul    ecx
  .text:004010EA               sar   edx, 1
  .text:004010EC               mov   eax, edx
  .text:004010EE               shr   eax, 1Fh
  .text:004010F1               add   eax, edx
  .text:004010F3               push    eax
  .text:004010F4               push    offset aDDDDD   ; "%d%d%d%d%d"
  .text:004010F9               call    sub_401020
  .text:004010FE               push    offset aPause   ; "pause"
  .text:00401103               call    sub_4048E7
  .text:00401108               add   esp, 28h
  .text:0040110B               xor   eax, eax
  .text:0040110D               mov   esp, ebp
  .text:0040110F               pop   ebp
  
  这里流水线优化等也不去掉了.可以发现跟VC6.0无任何区别
5.2 vs2019 x64有符号非2的幂优化  高级代码
int main(int argc, char* argv[])  {
  /*
  除法
  */
  __int64 NumberOne = 0;
  __int64 NumberTwo = 0;
  scanf("%I64d", &NumberOne);
  scanf("%I64d", &NumberTwo);
  __int64 Count1 = NumberOne / 3;
  __int64 Count2 = NumberTwo / 5;
  __int64 Count3 = NumberTwo / 6;
  __int64 Count4 = NumberTwo / 9;
  printf("%I64d%I64d%lld%lld", Count4, Count3, Count2, Count1);
  system("pause");
  return 0;
  }
  
  反汇编
text:00000001400010D0               sub   rsp, 38h  .text:00000001400010D4               xor   eax, eax
  .text:00000001400010D6               lea   rdx,
  .text:00000001400010DB               lea   rcx, aI64d      ; "%I64d"
  .text:00000001400010E2               mov   , rax
  .text:00000001400010E7               mov   , rax
  .text:00000001400010EC               call    sub_140001080
  .text:00000001400010F1               lea   rdx,
  .text:00000001400010F6               lea   rcx, aI64d      ; "%I64d"
  .text:00000001400010FD               call    sub_140001080
  .text:0000000140001102               mov   rcx,
  .text:0000000140001107               mov   rax, 5555555555555556h
  .text:0000000140001111               imul   
  .text:0000000140001116               mov   rax, 6666666666666667h
  .text:0000000140001120               mov   r10, rdx
  .text:0000000140001123               shr   r10, 3Fh
  .text:0000000140001127               add   r10, rdx
  .text:000000014000112A               imul    rcx
  .text:000000014000112D               mov   , r10
  .text:0000000140001132               mov   r9, rdx
  .text:0000000140001135               sar   r9, 1
  .text:0000000140001138               mov   rax, r9
  .text:000000014000113B               shr   rax, 3Fh
  .text:000000014000113F               add   r9, rax
  .text:0000000140001142               mov   rax, 2AAAAAAAAAAAAAABh
  .text:000000014000114C               imul    rcx
  .text:000000014000114F               mov   rax, 1C71C71C71C71C72h
  .text:0000000140001159               mov   r8, rdx
  .text:000000014000115C               shr   r8, 3Fh
  .text:0000000140001160               add   r8, rdx
  .text:0000000140001163               imul    rcx
  .text:0000000140001166               lea   rcx, aI64dI64dLldLld ; "%I64d%I64d%lld%lld"
  .text:000000014000116D               mov   rax, rdx
  .text:0000000140001170               shr   rax, 3Fh
  .text:0000000140001174               add   rdx, rax
  .text:0000000140001177               call    sub_140001020
  .text:000000014000117C               lea   rcx, aPause   ; "pause"
  .text:0000000140001183               call    sub_1400045C4
  .text:0000000140001188               xor   eax, eax
  .text:000000014000118A               add   rsp, 38h
  .text:000000014000118E               retn
  
  观看反汇编其实跟x86一致
  这里还是去掉流水线优化 提取核心代码位置进行反汇编
.text:0000000140001107               mov   rax, 5555555555555556h  .text:0000000140001111               imul   
  .text:0000000140001120               mov   r10, rdx
  .text:0000000140001123               shr   r10, 3Fh
  .text:0000000140001127               add   r10, rdx
  
  M数值变大.还是代入公式即可. 这里使用的mov r10,rdx 说明直接使用的rdx. rdx是一个64位数. 所以 2^64 / M = 2.9999999 向上取整 = 3
5.3 linux gcc x86 有符号非2的幂  高级代码
#include<stdio.h>  int main()
  {
  int NumberOne = 0;
  int NumberTwo = 0;
  scanf("%d", &NumberOne);
  scanf("%d", &NumberTwo);
  int Count1 = NumberOne / 3;
  int Count2 = NumberTwo / 5;
  int Count3 = NumberTwo / 6;
  int Count4 = NumberTwo / 9;
  printf("%d%d%d%d", Count4, Count3, Count2, Count1);
  scanf("%d", &Count4);
  scanf("%d", &Count3);
  scanf("%d", &Count2);
  scanf("%d", &Count1);
  printf("%d%d%d%d", Count4, Count3, Count2, Count1);
  return 0;
  }
  
  如果你是64位系统.那么你使用gcc命令如下
gcc xxx.c -o2 -m32  
  编译出来即可. 其实下面反汇编跟x86 vc++6.0 vs2019 一样.可以不用看了.
  反汇编
.text:080484BB ; int __cdecl main(int argc, const char **argv, const char **envp)  .text:080484BB               public main
  .text:080484BB main            proc near               ; DATA XREF: _start+17↑o
  .text:080484BB
  .text:080484BB var_24          = dword ptr -24h
  .text:080484BB var_20          = dword ptr -20h
  .text:080484BB var_1C          = dword ptr -1Ch
  .text:080484BB var_18          = dword ptr -18h
  .text:080484BB var_14          = dword ptr -14h
  .text:080484BB var_10          = dword ptr -10h
  .text:080484BB var_C         = dword ptr -0Ch
  .text:080484BB argc            = dword ptr8
  .text:080484BB argv            = dword ptr0Ch
  .text:080484BB envp            = dword ptr10h
  .text:080484BB
  .text:080484BB ; __unwind {
  .text:080484BB               lea   ecx,
  .text:080484BF               and   esp, 0FFFFFFF0h
  .text:080484C2               push    dword ptr
  .text:080484C5               push    ebp
  .text:080484C6               mov   ebp, esp
  .text:080484C8               push    ebx
  .text:080484C9               push    ecx
  .text:080484CA               sub   esp, 20h
  .text:080484CD               mov   eax, large gs:14h
  .text:080484D3               mov   , eax
  .text:080484D6               xor   eax, eax
  .text:080484D8               mov   , 0
  .text:080484DF               mov   , 0
  .text:080484E6               sub   esp, 8
  .text:080484E9               lea   eax,
  .text:080484EC               push    eax
  .text:080484ED               push    offset unk_80486B0
  .text:080484F2               call    ___isoc99_scanf
  .text:080484F7               add   esp, 10h
  .text:080484FA               sub   esp, 8
  .text:080484FD               lea   eax,
  .text:08048500               push    eax
  .text:08048501               push    offset unk_80486B0
  .text:08048506               call    ___isoc99_scanf
  .text:0804850B               add   esp, 10h
  .text:0804850E               mov   ecx,
  .text:08048511               mov   edx, 55555556h
  .text:08048516               mov   eax, ecx
  .text:08048518               imul    edx
  .text:0804851A               mov   eax, ecx
  .text:0804851C               sar   eax, 1Fh
  .text:0804851F               sub   edx, eax
  .text:08048521               mov   eax, edx
  .text:08048523               mov   , eax
  .text:08048526               mov   ecx,
  .text:08048529               mov   edx, 66666667h
  .text:0804852E               mov   eax, ecx
  .text:08048530               imul    edx
  .text:08048532               sar   edx, 1
  .text:08048534               mov   eax, ecx
  .text:08048536               sar   eax, 1Fh
  .text:08048539               sub   edx, eax
  .text:0804853B               mov   eax, edx
  .text:0804853D               mov   , eax
  .text:08048540               mov   ecx,
  .text:08048543               mov   edx, 2AAAAAABh
  .text:08048548               mov   eax, ecx
  .text:0804854A               imul    edx
  .text:0804854C               mov   eax, ecx
  .text:0804854E               sar   eax, 1Fh
  .text:08048551               sub   edx, eax
  .text:08048553               mov   eax, edx
  .text:08048555               mov   , eax
  .text:08048558               mov   ecx,
  .text:0804855B               mov   edx, 38E38E39h
  .text:08048560               mov   eax, ecx
  .text:08048562               imul    edx
  .text:08048564               sar   edx, 1
  .text:08048566               mov   eax, ecx
  .text:08048568               sar   eax, 1Fh
  .text:0804856B               sub   edx, eax
  .text:0804856D               mov   eax, edx
  
5.4 其它同理自己建立项目研究  自己建立项目研究.高手复习 新手学习 谢谢观看

角动量 发表于 2020-9-17 09:26:57

收藏一下,晚上再看

角动量 发表于 2020-9-17 10:00:31

1.2那些写错了哦,相加不是想加
页: [1]
查看完整版本: 反汇编代码还原之除数为非2的幂