【文章标题】: 完美学习编写汇编注册机
【文章作者】: aoanzhishu
【作者邮箱】: aoanzhishu@yahoo.com.cn
【软件名称】: 超级电话通3.05
【下载地址】: 自己搜索下载
【加壳方式】: ASPack 1.06b / 1.061b -> Alexey Solodovnikov
【保护方式】: 用户名
【使用工具】: OD+PEid
【操作平台】: XP (English)
【软件介绍】: 查询电话号码及地址
【作者声明】: 献给初学破解的朋友们,高手漂过,欢迎指点与建议,仅做为学习交流,别无其他目的
关于此软件的破解就不做介绍了,大家可以在看雪网站上搜到相关信息
我们很显然可以了解到注册算法为
for(i=1;i<=用户名长度;i++)
{
string=取用户名字符串的一个字符;
result=i && 0xff //i与 十六进制数ff 做 与 运算
result=result * string;
字符串指针指向下一个字符;
}
result=0xBEAE0 - result;
result=result 转化为十进制;
是不是挺简单的,我们不用C++ 等高级语言来实现注册机
直接用win32汇编其实在寄存器上能方便调用,有时还可以直接用反汇编的代码呢
关于win32 汇编 俺 推荐 大家学习 罗云彬 的 <<windows 环境下32 位汇编语言程序设计>>
好了下面开始分析注册机了:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 超级电话通3.05注册机
; by aoanzhishu 2008
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; reg.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386 ;这里是汇编语言的伪指令是386的指令集,应用程序运行在优先级3上,不会用到特权指令,只需定义.386
.model flat, stdcall ;.model工作模式 flat指Win32程序使用的模式运行在保护模式下,代码和数据段使用同一个4GB段;stdcall指子程序调用方式传递次序和
堆栈平衡的方法
option casemap :none ;格式,none 定义了程序中的变量区分大小写,由于win32 的 API 区分大小写,我们必须指定此项
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 定义标志符
ICO_MAIN equ 1000h ;主窗体图标ID
DLG_MAIN equ 1 ;主窗体ID
IDC_TEXTNAME equ 107 ;用户名输入框ID
IDC_TEXTCODE equ 108 ;注册码输入框ID
;注册函数声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GetReg proto ;注册码算法函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
result db 256 dup(0) ;要显示注册码的缓冲区
szFormat db "%d", 0 ;十进制 格式
.data?
hInstance dd ? ;窗体实例
@szBuffer db 256 dup(?) ;用户名缓冲区
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam ; 对话框窗体函数消息处理循环 函数 ,使用寄存器ebx,edi,esi,hWnd 为窗体句
柄,wMsg 为消息格式,wParam与lParam 为 消息内容(其实比这复杂,为了简单,就这么说了好懂些)
mov eax,wMsg ; 将当前消息移入 eax 中
.if eax == WM_CLOSE ; WM_CLOSE 是指 windows 的关闭窗体的消息ID
invoke EndDialog,hWnd,NULL ; invoke 是 win32 调用某种函数的方法 这里调用 EndDialog 顾名思义是指
结束窗体 到于参数请大家查 API 函数表
.elseif eax == WM_INITDIALOG ; WM_INITDIALOG 是指 windows 的 初始化窗体消息ID,只运行一次
;********************************************************************
; 设置标题栏图标
;********************************************************************
invoke LoadIcon,hInstance,ICO_MAIN ; 载入图标,返回句柄到eax中
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax ; 发送消息到windows 内容是 WM_SETICON 就是设置窗体图标
invoke GetDlgItem,hWnd,IDC_TEXTCODE ; 得到注册码输入框的ID的句柄到eax中
invoke EnableWindow,eax,FALSE ; 使注册码文本框不可用
.elseif eax == WM_COMMAND ; WM_COMMAND 是指 windows 的 命令消息ID
mov eax,wParam ; 从wParam中得到具体命令格式(只能这样说了,其实没这么简单的,想了解更详
细的的话,请查相关资料)
;********************************************************************
; 注册算法
;********************************************************************
.if ax == IDOK ; 点击了按钮
invoke GetReg ; Call 注册子函数,返回16进制数在edx中
invoke wsprintf,addr result,addr szFormat,edx ; 转换 edx 为 十进制
invoke SetDlgItemText,hWnd,IDC_TEXTCODE, addr result ; 显示 注册码到文本框
invoke GetDlgItem,hWnd,IDC_TEXTCODE ; 使注册码文本框可用
invoke EnableWindow,eax,TRUE
;********************************************************************
; 获取用户名到 szBuffer 缓冲区上
;********************************************************************
.elseif ax == IDC_TEXTNAME ; 正在输入用户名
invoke GetDlgItemText,hWnd,IDC_TEXTNAME,addr @szBuffer,sizeof @szBuffer
; 刷新 用户名输入框显示
.endif
;********************************************************************
.else
mov eax,FALSE ; 其他命令交给windows 自已处理
ret ; 中断返回
.endif
mov eax,TRUE
ret ; 中断返回
_ProcDlgMain endp ; 对话框窗体函数消息处理循环 函数 结束符
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start: ; 这里是整个程序运行的入口点
invoke GetModuleHandle,NULL ; 获取模块的实例句柄到eax中
mov hInstance,eax ; eax存入hInstance中
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
; 调用消息处理循环函数
invoke ExitProcess,NULL ; 退出程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;核心注册算法
GetReg proc
lea esi,@szBuffer ;将用户名存入esi寄存器
xor ecx,ecx ;ecx 归零
xor edx,edx ;edx 归零
_again: cmp ch,[esi] ;比较 ch (总为零) 与当前段偏移内的字符(当前字符)
je _finish ;如果为零,则表示已经到了用户名末尾,则表示已经循环完毕
inc cl ;不为零,使 cl(相当上面C++中的变量i) 增加 1 (也就是上面的伪代码的i++)
mov eax,ecx ;将 cl 存到 eax 中
and eax,0ffh ;eax 与 0xff 做 与运算,结果存入 eax 中
imul byte ptr [esi] ;al 与 当前字符 ASII 相乘,结果存入eax中
add edx,eax ;叠加 上次 edx 与 当前 结果 ,保存到 edx 中
inc esi ;指向下一个字符
jmp _again ;循环继续
_finish: ;运算结束
mov eax,0beae0h ;将 0xbeae0 存入eax 中
sub eax,edx ; 用 0xbeae0 - edx (上面循环结果)
mov edx,eax ; 将最后结果保存到 edx 寄存器中
ret
GetReg endp
end start ; 代码段结束
////////////////////////////////////////////////////////////////////////////////////////
reg.rc ; 资源文件
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 0x1000
#define DLG_MAIN 1
#define IDC_TEXTNAME 107
#define IDC_TEXTCODE 108
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 150, 160, 180, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "超级电话通3.05注册机"
FONT 9, "宋体"
{
GROUPBOX "输入框", -1, 27, 5, 125, 100, BS_GROUPBOX
LTEXT "用户名", -1, 35, 20, 105, 10
EDITTEXT IDC_TEXTNAME, 35, 35, 105, 12
LTEXT "注册码", -1, 35, 60, 105, 10
EDITTEXT IDC_TEXTCODE, 35, 75, 105, 12
DEFPUSHBUTTON "显示注册码", IDOK, 100, 115, 50, 14
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
后记:由此可见注册机也并不是那么难的.
在这里也感谢各位的支持...
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)