逆向-第三次实验-注册码分析
实验要求
利用OllyDbg,参照课程中的示例对EXP3.exe中的注册码进行分析并验证。
描述用OllyDbg对EXP3.exe进行分析的过程,回答EXP3中注册码的每一位应当是什么,并解释原因。
知识了解
我们需要了解到的一些指令
1.push
push 是一种汇编语言中的指令,用于将一个数据压入堆栈(stack)中。堆栈是一种后进先出(Last In First Out,LIFO)的数据结构,常用于存储函数的返回地址、函数参数、局部变量等信息。
push arg2 push arg1 call my_func
上述意为:将arg2,arg1压入堆栈,使用call指令调用函数‘my_func’
2.mov
mov 是一种汇编语言中的指令,用于将数据从一个地方移动到另一个地方。它的语法通常是 mov destination, source,其中 destination 是目的地,source 是来源。根据具体的汇编语言,目的地和来源可以是寄存器、内存地址、立即数等
mov eax, [address]
以上代码片段是 将内存地址 address 处的值复制到寄存器 eax 中
3.call
call 是一种汇编指令,用于调用一个子程序(subroutine)或函数。它的语法通常是 call address,其中 address 是子程序或函数的地址。
例如,以下代码片段中,call 指令用于调用名为 subroutine 的子程序:
call subroutine
4.test
test 是一种汇编指令,用于对两个操作数进行按位逻辑与(bitwise AND)运算,并更新标志寄存器的值。它的语法通常是 test destination, source,其中 destination 是目的地,source 是来源。根据具体的汇编语言,目的地和来源可以是寄存器、内存地址、立即数等。
test 指令会将 destination 和 source 的值按位进行逻辑与操作,并将结果更新到标志寄存器中。具体来说,它会将 destination 和 source 的每一位进行按位与运算,并将结果存储在标志寄存器中的相应位上。这样,程序可以根据标志寄存器的值来进行后续的条件跳转等操作。
例如,以下代码片段将对寄存器 eax 和立即数 10 进行按位逻辑与运算,并将结果更新到标志寄存器中:
test eax, 10
在汇编语言中,test 指令通常用于比较两个值的相等性或大小关系。例如,以下代码片段将比较寄存器 eax 和立即数 0 是否相等,并根据结果进行条件跳转:
test eax, eax
jz label
如果eax值为0,则跳转标签label处执行,否则执行下一条指令
5.je
je是一种汇编指令,用于实现条件跳转。它的语法通常是 je label,其中 label 是标签(label)的名称。je 指令的含义是:如果前一次的比较操作结果为相等,则跳转到标签 label 所在的位置执行。
je 指令通常和其他比较指令(如 cmp)配合使用,用于实现条件控制流程。例如,以下代码片段将比较寄存器 eax 和立即数 0 是否相等,如果相等,则跳转到标签 label 执行:
cmp eax, 0
je label
6.sub
sub 是汇编语言中的一种指令,用于实现两个操作数的减法运算。它的语法通常是 sub destination, source,其中 destination 表示目标操作数,source 表示源操作数。sub 指令的执行过程是将源操作数从目标操作数中减去,然后将结果存储到目标操作数中。
例如,以下代码将把 eax 寄存器中的值减去 ebx 寄存器中的值,并将结果存储到 eax 中:
sub eax, ebx
在执行 sub 指令时,首先将 ebx 寄存器中的值减去 eax 寄存器中的值,然后将结果存储到 eax 中,相当于执行了 eax = eax - ebx 的操作。
需要注意的是,在汇编语言中,sub 指令可以用于实现其他操作,如将内存地址指针减去一个常数。例如,以下代码将从 ebx 寄存器中的值减去 8,然后将结果存储到 esi 寄存器中的内存地址处:
sub dword ptr [esi], 8
在执行 sub 指令时,首先将内存地址 esi 处的值减去 8,然后将结果存储回内存地址 esi 中,相当于执行了 *(esi) = *(esi) - 8 的操作。
7.lea
lea 是汇编语言中的一种指令,用于计算一个内存地址的有效地址(effective address)并将其存储到寄存器中。lea 指令的语法通常是 lea destination, source,其中 destination 表示目标寄存器,source 表示源内存地址。lea 指令的执行过程中不涉及内存的读取或写入,只是对地址进行了简单的计算,并将计算结果存储到目标寄存器中
8.jnz
jnz 是汇编语言中的一种条件跳转指令,用于根据标志位 ZF(零标志位)的状态来跳转到指定的地址。jnz 的全称是 Jump if Not Zero,即当 ZF 不为 1(即非零)时跳转。
jnz 指令的语法通常是 jnz label,其中 label 是一个标记,表示跳转的目标地址。在执行 jnz 指令时,CPU 首先检查 ZF 的值,如果 ZF 不为 1(即非零),则跳转到 label 标记所在的代码位置执行,否则继续执行下一条指令。
例如,以下代码使用了 jnz 指令来实现一个简单的循环:
mov ecx, 10 ; 将计数器初始化为 10
loop_start:
; 循环体代码
dec ecx ; 计数器减 1
jnz loop_start ; 如果计数器不为 0,则跳转到循环起始处继续执行循环体
上述代码中,首先将计数器 ecx 初始化为 10,然后使用 dec 指令将计数器减 1,再使用 jnz 指令判断计数器是否为 0,如果计数器不为 0,则跳转到 loop_start 标记所在的位置继续执行循环体,否则跳出循环。
需要注意的是,jnz 指令仅在 ZF 不为 1(即非零)时跳转,因此在使用 jnz 指令之前,需要先根据需要设置或清除 ZF 标志位。通常情况下,jnz 指令用于实现循环、条件分支等逻辑结构。
9.jmp
jmp 是汇编语言中的无条件跳转指令,用于无条件地跳转到指定的地址执行代码。jmp 的全称是 Jump,即直接跳转。
jmp 指令的语法通常是 jmp label 或 jmp address,其中 label 是一个标记,表示跳转的目标地址,而 address 则是一个具体的地址,表示跳转的目标地址。在执行 jmp 指令时,CPU 会直接跳转到指定的地址继续执行代码,而不会考虑任何条件。
例如,以下代码使用了 jmp 指令来实现一个简单的无限循环:
loop:
; 循环体代码
jmp loop ; 无条件跳转到 loop 标记所在的位置继续执行循环体
在上述代码中,使用了一个标记 loop 来表示循环的起始位置,在循环体代码执行完成后,使用 jmp 指令无条件跳转到 loop 标记所在的位置,从而实现了一个无限循环。
需要注意的是,由于 jmp 指令是无条件跳转,因此在使用 jmp 指令时需要格外小心,避免出现无限循环、死循环等问题。一般情况下,jmp 指令多用于实现函数调用、中断处理等场景
10.short
在汇编语言中,short 是一个标识符,通常用于指定一个短跳转地址。在实模式下,使用 short 可以实现跳转到相对于当前地址的较短距离。
具体来说,short 的语法通常是 short label,其中 label 是一个标记,表示跳转的目标地址。在执行 short 指令时,CPU 会将跳转的目标地址视为当前地址加上一个 8 位的偏移量,因此,short 指令所能够跳转到的地址范围比较有限。
例如,以下代码使用了 short 指令来实现一个简单的循环:
start: ; 循环体代码 jmp short start ; 短跳转到 start 标记所在的位置继续执行循环体
在上述代码中,使用了一个标记 start 来表示循环的起始位置,在循环体代码执行完成后,使用 jmp short 指令短跳转到 start 标记所在的位置,从而实现了一个循环。
需要注意的是,由于 short 指令所能够跳转到的地址范围比较有限,因此在实际编程中,一般不建议过度依赖 short 指令,而应该使用其他更为灵活的跳转方式。
11.shl
将一个二进制数的所有位向左移动指定的位数,最低位补 0。
shl destination, count
其中,destination 是要移位的操作数,count 是移位的位数。例如,shl ax, 1 操作将寄存器 ax 左移一位,相当于将 ax 中的值乘以 2。
实验操作
如图注释:
在针对 ascii码的字符串搜索得到srial is correct
我们猜测这是我们想要的代码位置
接着我们对指令进行解读
首先用call调用了 函数GetdigitemtextA
读取字符长度并储存到了 eax
接着是用cmp将eax与8进行比较
可以发现jnz都是指向一个 地址,即有任何一个地方出错都会转入该地址
接下来对下面的cmp前打上断点,然后运行,输入12345678代表注册码 位数,接着 运行,程序会在这停止运行,接着 对右边寄存器的 esp的数值进行数据追踪,
会在左下角的位置显示,可以看到我们输入的注册码,如下图
再根据汇编指令,+0x9,以为有0x0,所以向右数10个,找到第十个数据,看它对应哪一位注册码
得出位置后,看下面的指令要求我们输入什么数
如第一个指令指注册码第六位 与0x2D的ascii码相等
下面的每次分析都是单独的块单独分析 ,步骤相同
唯一的区别是指令不同
分别列举
cmp a,b:将ab进行比较 ,相等为0,相当于两值相减
shl a,b:对二进制数据a进行一次左移位b位。
mov:将后面的值传进前面的变量上
movsx:带符号的传递
test eax,eax
je label
:如果eax是0就会进入下面的label里
add:加法
最后答案看图很容易得出,手操并不难。
本文来自博客园,作者:逆世混沌,转载请注明原文链接:https://www.cnblogs.com/nish1hundun/p/17260656.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步