该看的资料都看过了,是时候做下练习了,在百度搜了个C语言常用算法.docx。便拿起最简单的一个小算法来练习下反汇编了
程序源代码:
#include<stdio.h>
#include<stdlib.h>
int sushu(int m);
void main()
{
int m,k;
printf("please input a number:\n");
scanf("%d",&m);
k=sushu(m);
if(k==m)
printf("该数是素数\n");
else
printf("该数不是素数\n");
system("pause");
}
int sushu(int m)
{
int i;
for(i=2;i*i<=m;i++)
if(m%i==0)
return 0;
return m;
}
逆向思路:
用OD打开程序 F8单步走,走到一个Call 卡主,因为程序在正式运行了,要求输入了
在那个call下断点重新加载程序 F9运行到断点,然后F7跟进CALL。
Call里面是主程序内容,这里主要分析sushu函数,再走几步找到sushu函数进去,汇编代码:
00401000 56 push esi
00401001 8B7424 08 mov esi,dword ptr ss:[esp+8] ; esi作传进来的参数
00401005 83FE 04 cmp esi,4 ; m<=i*i
00401008 B9 02000000 mov ecx,2 ; i=2
0040100D 7C 14 jl short asm.00401023 ; 小于4的话直接跳过 返回素数本身
0040100F 90 nop
00401010 8BC6 mov eax,esi ; 参数暂时给eax
00401012 99 cdq ; 将eax的符号位扩展到edx
00401013 F7F9 idiv ecx ; 合并后除以ecx 商放在eax 余数放在edx
00401015 85D2 test edx,edx
00401017 74 0E je short asm.00401027 ; 如果等于0,即没有余数 就判断它不是素数
00401019 41 inc ecx ; i++;
0040101A 8BC1 mov eax,ecx
0040101C 0FAFC1 imul eax,ecx ; 综合两句得 i*i
0040101F 3BC6 cmp eax,esi
00401021 ^ 7E ED jle short asm.00401010 ; i*i小于等于4则循环继续
00401023 8BC6 mov eax,esi
00401025 5E pop esi
00401026 C3 retn
00401027 33C0 xor eax,eax
00401029 5E pop esi
0040102A C3 retn