逆向笔记

大一上学期的一些笔记:

1.用堆栈存放局部变量
编译器非优化模式下用ebp寻址。ebp-xxxx    参数则为ebp+xxxx
编译器优化模式下用esp直接寻址
2.局部变量分配与清除堆栈:
一、sub esp,n
…………
add esp,n
二、add esp,-n
…………
sub esp,-n
三、push reg(reg为某个寄存器)
…………
pop reg
3.利用寄存器存放局部变量:
如果寄存器不够用,会利用堆栈。逆向时必须及时确定当前寄存器的变量是哪个变量。
4.如果函数有两个参数,用ebp传址,则两参数地址一般为ebp+08  ebp+0c
push ebp
mov ebp,esp
push ecx
mov eax,dword ptr [ebp+08]
mov ecx,dword ptr [ebp+0c]
………………
5。全局变量一般位于.idata区的一个固定地址上,访问时直接用硬编码的地址直接对内存寻址.
6.数组:基址加变址寻址
7.开始时xor一个寄存器往往是将其作为一个变量使用。
【基址+n】一般为给数组或结构赋值,其中基址为常量或寄存器。
8.lea有时等价于add
lea eax,[eax+8]等价于add eax+8
lea的效率远远高于add,这种技巧可以使多个变量的求和在一个指令周期内完成
9.大写字母:41h——5Ah大写字母的第5位为0
小写字母:61h——7Ah小写字母的第5位为1
10.c语言strlen()在优化模式下的汇编代码:
mov ecx,FFFFFFFF    ;如果看到这句,程序很可能是要获得字符串的长度了
sub eax,eax
repnz
scasb
not ecx
dec ecx
je xxxxxxxx
11.测试寄存器是否为0:
cmp eax,00000000h

or eax,eax

test eax,eax
12.置寄存器0FFFFFFFFh
xor eax,eax/sub eax,eax
dec eax

stc
sbb eax,eax
13.转移指令:
jmp _lable_

push _lable_
ret
14.获取编辑框字符串常用api:
GetWindowTextA(W)
GetDlgItemTextA(W)
GetDlgItemInt
判断完注册码后常常显示对话框,告诉用户是否正确,显示对话框的常用api:
MessageBoxA(W)
MessageBoxExA(W)
MessageboxIndirectA(W)
DialogBoxParamA(W)
DialogboxIndirectParamA(W)
CreateDialogParamA(W)
CreateDialogIndirectParamA(W)
ShowWindow
程序每次启动都会将注册码读出来加以判断,决定是否以注册版的模式工作,根据序列号放置位置不同,可用不同的api断点:
(1)序列号在注册表中:可用RegQueryValueExA(W)
(2)序列号在ini文件中:可用GetPrivateProfileStringA(W)、GetPrivateProfileIntA(W)、GetProfileStringA(W)、GetProfileIntA(W)
(3)序列号在一般文件中,CreateFileA(W)、_lopen()
15.数据约束性(密码相邻性):(仅限于明文比较注册码的保护方式)真正正确的注册码会在某个时刻出现在内存中,但位置不定。大多数情况下会在输入序列号的内存地址+-90h的地方。它们会共同位于一个小堆栈区域(加密者一般用局部变量放临时计算出来的注册码),使得它们可以在同一个watch窗口中看到。
16.模块句柄hInstance是实例的基地址
17.DialogBoxParam函数原型:
int DialogBoxParam(
HINSTANCE hInstance,    模块句柄
LPCTSTR lpTemplateName,    对话框ID
HWND hWndParent,    父窗口句柄
DLGPROC lpDialogFunc,    对话框处理函数指针(程序会跳到这里执行)
LPARAM dwInitParam    初始化值
);
18.去除某个对话框的方法:
先用exescope打开查看资源,若对话框为资源,记下ID,用w32dasm,打开对话框参考,找到对应id的对话框,双击来到代码处。
若为DialogBoxParam,用jmp跳过(EndDialog后面)
若主窗口也为DialogBoxParam则可修改前一个DialogBoxParam的TemplateName和lpDialogFunc使之指向主窗口。
对话框不是资源时,而常用断点又拦不下来,这是可以试试消息断点。如WM_DESTROY。
19.时间限制:
(1)每次运行多少时间
(2)时间段限制,如用30天
(1)
SetTimer函数:
UINT SetTimer(HWND hWnd,UINT nIDEvent,UINT uElapse,TIMERPROC lpTimerFunc)
hWnd        窗口句柄
nIDEvent    计时器标识
uElapse        指定计时器时间间隔,单位毫秒
lpTimerFunc    回调函数,超时时系统调用该函数,如果为NULL,则超时将向相应窗口发送WM_TIMER消息
该callback函数原型:
void CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
KillTimer()销毁计时器
timeSetEvent(…………)多媒体计时器
GetTickCount()返回系统自成功启动以来的时间(毫秒数)(两次调用相减就得到程序运行时间)
c语言用time()获取系统时间
(2)
取得时间的api:
GetSystemTime
GetLocalTime
GetFileTime
软件主要记录两个时间:
(1)首次运行时间
(2)上次运行时间(每次运行时都获取一次系统时间,若大于上次运行时间,则更新,不然则说明用户将系统时间改回去了)
时间一般记录在注册表或文件或扇区中,不起眼的地方
#define WM_TIMER 0×0113
可见WM_TIMER就是0×0113

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>