键盘记录2003算法分析
目标:键盘记录2003
作者:LFTBirthday
类型:明码比较,无壳。
工具:olly
0041F87B E8 D4DF0100
CALL <JMP.&MFC42.#3098>
; 读入第一个输入框的姓名MFC42.#3098
0041F880 80BD 68FFFFFF 00 CMP BYTE PTR SS:[EBP-98],0
; [EBP-98]处存放FTBirthday,判断是否为空
0041F887 75 18 JNZ SHORT FTBirthd.0041F8A1
; 不为空则继续ORT
FT
0041F889 6A 40 PUSH 40
0041F88B 68 0CEE4000 PUSH FTBirthd.0040EE0C
;
ASCII "Attention!"
0041F890 68 F4ED4000 PUSH FTBirthd.0040EDF4
;
ASCII "Please enter your name!"
0041F895 8BCF MOV ECX,EDI
0041F897 E8 BEDF0100 CALL <JMP.&MFC42.#4224>
0041F89C E9 FA000000 JMP FTBirthd.0041F99B
0041F8A1 56 PUSH ESI
; ESI入栈ES
0041F8A2 6A 0A PUSH 0A
; 0A入栈 0
0041F8A4 5E POP ESI
; OA给ESI,ESI=0000000A
0041F8A5 8D45 E8 LEA EAX,DWORD PTR
SS:[EBP-18] ; 把[EBP-18]=0012E508的有效值(=内存地址)给EAX
0041F8A8 56 PUSH ESI
0041F8A9 50 PUSH EAX
0041F8AA 68 DAD60000 PUSH 0D6DA
0041F8AF 8BCF MOV ECX,EDI
0041F8B1 E8 9EDF0100 CALL <JMP.&MFC42.#3098>
;
读入注册码第一部分,EAX为位数,12E508处存放注册码第一部分四位
0041F8B6 8D45 D0 LEA EAX,DWORD PTR
SS:[EBP-30] ; 把[EBP-30]=0012E4F0的有效值(=内存地址)给EAX
0041F8B9 56 PUSH ESI
0041F8BA 50 PUSH EAX
0041F8BB 68 DBD60000 PUSH 0D6DB
0041F8C0 8BCF MOV ECX,EDI
0041F8C2 E8 8DDF0100 CALL <JMP.&MFC42.#3098>
;
读入注册码第二部分,EAX为位数,12E4F0处存放注册码第二部分四位
0041F8C7 8D45 DC LEA EAX,DWORD PTR
SS:[EBP-24] ; 把[EBP-24]=0012E4FC的有效值(=内存地址)给EAX
0041F8CA 56 PUSH ESI
0041F8CB 50 PUSH EAX
0041F8CC 68 DCD60000 PUSH 0D6DC
0041F8D1 8BCF MOV ECX,EDI
0041F8D3 E8 7CDF0100 CALL <JMP.&MFC42.#3098>
;
读入注册码第三部分,EAX为位数,0012E4FC处存放注册码第三部分四位
0041F8D8 8D45 F4 LEA EAX,DWORD PTR
SS:[EBP-C] ; 把[EBP-C]=0012E514的有效值(=内存地址)给EAX
0041F8DB 56 PUSH ESI
0041F8DC 50 PUSH EAX
0041F8DD 68 DDD60000 PUSH 0D6DD
0041F8E2 8BCF MOV ECX,EDI
0041F8E4 E8 6BDF0100 CALL <JMP.&MFC42.#3098>
;
读入注册码第四部分,EAX为位数,12E514处存放注册码第四部分四位
0041F8E9 8D45 E8 LEA EAX,DWORD PTR
SS:[EBP-18] ; EAX
0012E508 ASCII "1111"
0041F8EC 50 PUSH EAX
0041F8ED 8D45 9C LEA EAX,DWORD PTR
SS:[EBP-64] ; EAX
0012E4BC
0041F8F0 50 PUSH EAX
0041F8F1 FF15 40114000 CALL DWORD PTR DS:[<&KERNEL32.lstrcpyA>]
; kernel32.lstrcpyA
0041F8F7 8B35 48114000 MOV ESI,DWORD PTR DS:[<&KERNEL32.lstrcatA>]
; kernel32.lstrcatA
0041F8FD 8D45 D0 LEA EAX,DWORD PTR
SS:[EBP-30] ; EAX
0012E4F0 ASCII "2222"
0041F900 50 PUSH EAX
0041F901 8D45 9C LEA EAX,DWORD PTR
SS:[EBP-64] ; EAX
0012E4BC ASCII "1111"
0041F904 50 PUSH EAX
0041F905 FFD6 CALL ESI
; EAX 0012E4BC ASCII "11112222"
0041F907 8D45 DC LEA EAX,DWORD PTR
SS:[EBP-24] ; EAX
0012E4FC ASCII "3333"
0041F90A 50 PUSH EAX
0041F90B 8D45 9C LEA EAX,DWORD PTR
SS:[EBP-64] ; EAX
0012E4BC ASCII "11112222"
0041F90E 50 PUSH EAX
0041F90F FFD6 CALL ESI
; EAX 0012E4BC ASCII "111122223333"
0041F911 8D45 F4 LEA EAX,DWORD PTR
SS:[EBP-C] ; EAX
0012E514 ASCII "4444"
0041F914 50 PUSH EAX
0041F915 8D45 9C LEA EAX,DWORD PTR
SS:[EBP-64] ; EAX
0012E4BC ASCII "1111222233334444"
0041F918 50 PUSH EAX
0041F919 FFD6 CALL ESI
; EAX 0012E4BC ASCII "1111222233334444"
0041F91B 8D85 34FFFFFF LEA EAX,DWORD PTR SS:[EBP-CC]
; EAX 0012E454
0041F921 50 PUSH EAX
0041F922 8D85 68FFFFFF LEA EAX,DWORD PTR SS:[EBP-98]
; EAX 0012E488 ASCII "FTBirthday"
0041F928 68 00434000 PUSH FTBirthd.00404300
;
参数1 ASCII "_r <@~=nj/2[l5,^"
0041F92D 50 PUSH EAX
; 参数2,用户名X
0041F92E E8 61FEFFFF CALL FTBirthd.0041F794
;
关键CALL,EAX 0012E454 ASCII "ANXKAKKKLLQPVRTR"
0041F933 83C4 0C ADD ESP,0C
0041F936 8D45 9C LEA EAX,DWORD PTR
SS:[EBP-64] ; EAX
0012E4BC ASCII "1111222233334444"
0041F939 50 PUSH EAX
0041F93A 8D85 34FFFFFF LEA EAX,DWORD PTR SS:[EBP-CC]
; EAX 0012E454 ASCII "ANXKAKKKLLQPVRTR"
0041F940 50 PUSH EAX
0041F941 FF15 20114000 CALL DWORD PTR DS:[<&KERNEL32.lstrcmpiA>]
; kernel32.lstrcmpiA
0041F947 5E POP ESI
0041F948 85C0 TEST EAX,EAX
; 将由用户名处理得到的注册码和输入的注册码比较
0041F94A 6A 40 PUSH 40
0041F94C 75 31 JNZ SHORT FTBirthd.0041F97F
0041F94E 68 E4ED4000 PUSH FTBirthd.0040EDE4
;
ASCII "Registration"
0041F953 68 A0ED4000 PUSH FTBirthd.0040EDA0
;
ASCII "Registration succeeded. Thank you for choosing Perfect Keylogger!"
0041F958 8BCF MOV ECX,EDI
0041F95A E8 FBDE0100 CALL <JMP.&MFC42.#4224>
0041F95F 8D85 68FFFFFF LEA EAX,DWORD PTR SS:[EBP-98]
0041F965 8D4F 64 LEA ECX,DWORD PTR
DS:[EDI+64]
0041F968 50 PUSH EAX
0041F969 E8 24DA0100 CALL <JMP.&MFC42.#860>
0041F96E 8D45 9C LEA EAX,DWORD PTR
SS:[EBP-64]
0041F971 8D4F 60 LEA ECX,DWORD PTR
DS:[EDI+60]
0041F974 50 PUSH EAX
0041F975 E8 18DA0100 CALL <JMP.&MFC42.#860>
0041F97A 6A 01 PUSH 1
0041F97C 58 POP EAX
0041F97D EB 1E JMP SHORT FTBirthd.0041F99D
0041F97F 68 8CED4000 PUSH FTBirthd.0040ED8C
;
ASCII "Registration error"
0041F984 68 38ED4000 PUSH FTBirthd.0040ED38
;
ASCII "Registration code or user name is invalid. Please check all fields
and try again!"
0041F989 8BCF MOV ECX,EDI
0041F98B E8 CADE0100 CALL <JMP.&MFC42.#4224>
0041F990 68 2C010000 PUSH 12C
0041F995 FF15 38114000 CALL DWORD PTR DS:[<&KERNEL32.Sleep>]
; kernel32.Sleep
0041F99B 33C0 XOR EAX,EAX
0041F99D 5F POP EDI
0041F99E C9 LEAVE
0041F99F C3 RETN
进入关键call看看
0041F795 8BEC MOV EBP,ESP
0041F797 51 PUSH ECX
0041F798 51 PUSH ECX
0041F799 53 PUSH EBX
0041F79A 56 PUSH ESI
0041F79B FF75 0C PUSH DWORD PTR SS:[EBP+C]
0041F79E 8B35 B4104000 MOV ESI,DWORD PTR DS:[<&KERNEL32>;
kernel32.lstrlenA
0041F7A4 FFD6 CALL ESI
; EAX 10注册码长度,EDX "_r <@~=nj/2[l5,^"
0041F7A6 FF75 08 PUSH DWORD PTR SS:[EBP+8]
0041F7A9 8BD8 MOV EBX,EAX
;
EBX=10
0041F7AB 895D FC MOV DWORD PTR SS:[EBP-4],EBX
0041F7AE FFD6 CALL ESI
; EAX A用户名长度,EDX "FTBirthday"
0041F7B0 8BF0 MOV ESI,EAX
;
ESI=A
0041F7B2 85F6 TEST ESI,ESI
;
判断用户名是否为空ESI
0041F7B4 8975 F8 MOV DWORD PTR SS:[EBP-8],ESI
; [EBP-8]=0012E430=0A 00 00 00
0041F7B7 75 08 JNZ SHORT FTBirthd.0041F7C1
; 不为零则跳,为空OVER
0041F7B9 8B45 10 MOV EAX,DWORD PTR
SS:[EBP+10]
0041F7BC 8020 00 AND BYTE PTR DS:[EAX],0
0041F7BF EB 4E JMP SHORT FTBirthd.0041F80F
0041F7C1 57 PUSH EDI
; 一切正常,就到这里
0041F7C2 8B7D 10 MOV EDI,DWORD PTR
SS:[EBP+10]
0041F7C5 FF75 0C PUSH DWORD PTR SS:[EBP+C]
0041F7C8 57 PUSH EDI
0041F7C9 FF15 40114000 CALL DWORD PTR DS:[<&KERNEL32.ls>;
把"_r <@~=nj/2[l5,^"复制到EAX
0041F7CF 3BF3 CMP ESI,EBX
;
判断用户名长度是否大于注册码
0041F7D1 8975 0C MOV DWORD PTR SS:[EBP+C],ESI
; [EBP+C]=0A
0041F7D4 7F 03 JG SHORT FTBirthd.0041F7D9
; 大于则跳HORT
0041F7D6 895D 0C MOV DWORD PTR SS:[EBP+C],EBX
; [EBP+C]=10
0041F7D9 33F6 XOR ESI,ESI
;
ESI清零
0041F7DB 3975 0C CMP DWORD PTR SS:[EBP+C],ESI
; 判断有没有输入注册码
0041F7DE 7E 2C JLE SHORT FTBirthd.0041F80C
0041F7E0 8BC6 MOV EAX,ESI
;
算法循环开始,EAX初值为0
0041F7E2 6A 19 PUSH 19
0041F7E4 99 CDQ
; EDX置零
0041F7E5 F77D FC IDIV DWORD PTR SS:[EBP-4]
; EAX idiv 注册码长度(EBP-4=10),商放入EAX,余数放入EDX
0041F7E8 8BC6 MOV EAX,ESI
0041F7EA 5B POP EBX
0041F7EB 8D0C3A LEA ECX,DWORD PTR
DS:[EDX+EDI] ; 字符串第[余数+1]位开始给ECX
0041F7EE 99 CDQ
; EDX置零
0041F7EF F77D F8 IDIV DWORD PTR SS:[EBP-8]
; EAX idiv 用户名长度(EBP-8=A),商放入EAX,余数放入EDX
0041F7F2 8B45 08 MOV EAX,DWORD PTR
SS:[EBP+8] ; "FTBirthday"给EAXR
0041F7F5 0FB60402 MOVZX EAX,BYTE PTR DS:[EDX+EAX]
; 取用户名的第[余数+1]位
0041F7F9 0FB611 MOVZX EDX,BYTE PTR
DS:[ECX] ; 取ECX处字符串的第一位
0041F7FC 33C2 XOR EAX,EDX
;
异或,结果放入EAX
0041F7FE 99 CDQ
; EDX置零
0041F7FF F7FB IDIV EBX
; 异或结果idiv19,商放入EAX,余数放入EDX
0041F801 80C2 41 ADD DL,41
;
余数+41
0041F804 46 INC ESI
; 循环指针加1
0041F805 3B75 0C CMP ESI,DWORD PTR
SS:[EBP+C] ; 比较循环是否结束,[EBP+C]=0012E444="10 00 00 00"
0041F808 8811 MOV BYTE PTR
DS:[ECX],DL ; DL即为注册码的下一位
0041F80A ^7C D4 JL SHORT FTBirthd.0041F7E0
; 小于则跳回继续
0041F80C 8BC7 MOV EAX,EDI
;
结束后把最终结果放入EAX
0041F80E 5F POP EDI
0041F80F 5E POP ESI
0041F810 5B POP EBX
0041F811 C9 LEAVE
0041F812 C3 RETN
模拟算法验证
用户名"FTBirthday"
即"46 54 42 69 72 74 68 64 61 79" =A[i]
字符串"_r <@~=nj/2[l5,^" 即"5F 72 20 3C 40 7E 3D 6E 6A 2F 32
5B 31 35 2C 5E" =B[i]
初始ESI=0 EAX=0
注册码第一位={A[0 idiv A的余数] xor B[0 idiv 10的余数]}idiv 19的余数+41
={A[0] xor B[0]}idiv 19的余数+41
={46 xor 5F}idiv 19的余数+41
=19 idiv 19的余数+41=0+41=41="A"
注册码第二位={A[1 idiv A的余数] xor B[1
idiv 10的余数]}idiv 19的余数+41
={A[1] xor B[1]}idiv 19的余数+41
={54 xor 72}idiv 19的余数+41
=26 idiv 19的余数+41=D+41=4E="N"
注册码第三位={A[2 idiv A的余数] xor B[2
idiv 10的余数]}idiv 19的余数+41
={A[2] xor B[2]}idiv 19的余数+41
={42 xor 20}idiv 19的余数+41
=62 idiv 19的余数+41=17+41=58="X"
注册码第四位={A[3 idiv A的余数] xor B[3
idiv 10的余数]}idiv 19的余数+41
={A[3] xor B[3]}idiv 19的余数+41
={69 xor 3C}idiv 19的余数+41
=55 idiv 19的余数+41=A+41=4B="K"
………………
注册码第十一位={A[A idiv A的余数] xor B[A
idiv 10的余数]}idiv 19的余数+41
={A[0] xor B[A]}idiv 19的余数+41
={46 xor 32}idiv 19的余数+41
=74 idiv 19的余数+41=10+41=51="Q"
………………
注册码第十六位={A[F idiv A的余数] xor B[F
idiv 10的余数]}idiv 19的余数+41
={A[5] xor B[F]}idiv 19的余数+41
={74 xor 5E}idiv 19的余数+41
=2A idiv 19的余数+41=11+41=52="R"
所以示例注册码为
用户名:"FTBirthday"
注册码:"ANXK-AKKK-LLQP-VRTR"