|

楼主 |
发表于 2021-1-28 09:33:48
|
显示全部楼层
本帖最后由 yjmwxwx 于 2021-1-28 09:45 编辑
要写算号器也不难,就是我C语言不怎么会用
看懂下面这两个函数就能写算号器了
这个是显示ID号的,只是把ID号码简单移位来显示
- seg000:080198B0 LDR R0, =unk_2001AFC8 ; 96位ID储存地址
- seg000:080198B2 LDR R1, =a04x04x04x04x04 ; "%04X-%04X-%04X-%04X-%04X-%04X"
- seg000:080198B4 PUSH.W {R4-R10,LR}
- seg000:080198B8 LDRB R2, [R0,#1]
- seg000:080198BA SUB SP, SP, #0x10
- seg000:080198BC LDRB R5, [R0]
- seg000:080198BE LDRB R3, [R0,#3]
- seg000:080198C0 LDRB R4, [R0,#2]
- seg000:080198C2 ADD.W R2, R2, R5,LSL#8
- seg000:080198C6 LDRB R7, [R0,#5]
- seg000:080198C8 ADD.W R3, R3, R4,LSL#8
- seg000:080198CC LDRB R5, [R0,#4]
- seg000:080198CE LDRB R6, [R0,#7]
- seg000:080198D0 SXTH R2, R2
- seg000:080198D2 LDRB R4, [R0,#6]
- seg000:080198D4 ADD.W R7, R7, R5,LSL#8
- seg000:080198D8 LDRB R5, [R0,#9]
- seg000:080198DA SXTH R3, R3
- seg000:080198DC LDRB.W LR, [R0,#8]
- seg000:080198E0 ADD.W R6, R6, R4,LSL#8
- seg000:080198E4 LDRB R4, [R0,#0xB]
- seg000:080198E6 SXTH R7, R7
- seg000:080198E8 LDRB R0, [R0,#0xA]
- seg000:080198EA ADD.W R5, R5, LR,LSL#8
- seg000:080198EE SXTH R6, R6
- seg000:080198F0 STR R7, [SP]
- seg000:080198F2 ADD.W R4, R4, R0,LSL#8
- seg000:080198F6 LDR R0, =unk_20006190
- seg000:080198F8 SXTH R5, R5
- seg000:080198FA STR R6, [SP,#4]
- seg000:080198FC SXTH R4, R4
- seg000:080198FE STR R5, [SP,#8]
- seg000:08019900 STR R4, [SP,#0xC]
复制代码
下面这个是从ID号计算密码的,这个注释写的有点差劲。。
- seg000:0800D748 ; ID
- seg000:0800D748 ; r0=ID地址0x2001AFC8
- seg000:0800D748
- seg000:0800D748 sub_800D748 ; CODE XREF: sub_8019AF8+2E↓p
- seg000:0800D748 PUSH {R4-R6}
- seg000:0800D74A MOVS R2, #0 ; R2=0
- seg000:0800D74C SUBS R3, R0, #1 ; R3=R0-1
- seg000:0800D74E ADD.W R5, R0, #0xB ; R5=R0+0X0B
- seg000:0800D752
- seg000:0800D752 loc_800D752 ; CODE XREF: sub_800D748+12↓j
- seg000:0800D752 LDRSB.W R4, [R3,#1]! ; 读8位ID
- seg000:0800D756 CMP R5, R3
- seg000:0800D758 ADD R2, R4 ; ID累加
- seg000:0800D75A BNE loc_800D752 ; 读8位ID
- seg000:0800D75C LDRSB.W R3, [R0] ; 读ID 最低8位
- seg000:0800D760 UBFX.W R2, R2, #0, #0xA ; 提取10位
- seg000:0800D764 LDRSB.W R4, [R0,#0xB] ; 读ID最高8位
- seg000:0800D768 SUBS R0, R1, #1 ; R0=0X2001AF54-1
- seg000:0800D76A LDR R6, =unk_2001AE88
- seg000:0800D76C ADDS R1, #7 ; R1=0X200001AF54 + 7
- seg000:0800D76E ADD R3, R4 ; ID最高8位+ID最低8位
- seg000:0800D770 LDR R5, =0x20001AC8
- seg000:0800D772 LDR R4, =unk_2001AE8C
- seg000:0800D774 ADD R3, R2 ; 最高8位+最低8位结果+ID累加提取的10位
- seg000:0800D776 STR R2, [R6] ; ID累加提取的10位
- seg000:0800D776 ; 保存到
- seg000:0800D776 ; 0x2001AE88
- seg000:0800D778 UBFX.W R3, R3, #0, #0xA ; ID最高8位
- seg000:0800D778 ; 加
- seg000:0800D778 ; ID最低8位
- seg000:0800D778 ; 加
- seg000:0800D778 ; ID累加结果提取的10位
- seg000:0800D778 ; 的结果
- seg000:0800D778 ; 提取10位
- seg000:0800D77C STR R3, [R4] ; 保存到
- seg000:0800D77C ; 0x2001AE8C
- seg000:0800D77E
- seg000:0800D77E loc_800D77E ; CODE XREF: sub_800D748+46↓j
- seg000:0800D77E LDR.W R4, [R5,R3,LSL#2] ;
- seg000:0800D77E ; r5=0x20001AC8
- seg000:0800D77E ; 加
- seg000:0800D77E ; r3
- seg000:0800D77E ; 地址的数据放到
- seg000:0800D77E ; R4
- seg000:0800D782 ADD R3, R2 ; r3
- seg000:0800D782 ; +
- seg000:0800D782 ; ID蕾姐结果提取10位
- seg000:0800D784 STRB.W R4, [R0,#1]! ;
- seg000:0800D784 ; r4=0x20001ac8里面的数据
- seg000:0800D784 ; 写到
- seg000:0800D784 ; R0=0x2001AF54
- seg000:0800D788 CMP R1, R0 ;
- seg000:0800D788 ; R0=0x2001af54
- seg000:0800D788 ; r1=0X20001AF5C
- seg000:0800D788 ; 复制16位
- seg000:0800D78A UBFX.W R3, R3, #0, #0xA ; R3提取10位
- seg000:0800D78E BNE loc_800D77E
- seg000:0800D790 POP {R4-R6}
- seg000:0800D792 BX LR
复制代码
上面这个0X20001AC8和2001AE88肯定有关联的,可能通过读0X20001ACU+指针指向了0X2001AE88
我C语言不熟悉,不知道怎么写,下面这个不成功,前面从序列号移位的对,后面这个不知道用C语言怎么写,贴出来帮忙看看要怎么改
- #include <stdio.h>
- void main() {
- unsigned int di_32, zhong_32, gao_32; //序列号
- unsigned int wei8_0, wei8_1, wei8_2, wei8_3;
- unsigned int wei8_4, wei8_5, wei8_6, wei8_7;
- unsigned int wei8_8, wei8_9, wei8_a, wei8_b;
- unsigned char mima[8];
- unsigned int ID[30000];
- di_32 = 0x44332211;
- zhong_32 = 0x77665544;
- gao_32 = 0xbbaa9988;
- wei8_0 = (di_32 & 0xff00) >> 8;
- wei8_1 = (di_32 & 0xff) << 8;
- wei8_2 = (di_32 & 0xff000000) >> 8;
- wei8_3 = (di_32 & 0xff0000) << 8;
- wei8_4 = (zhong_32 & 0xff00) >> 8;
- wei8_5 = (zhong_32 & 0xff) << 8;
- wei8_6 = (zhong_32 & 0xff000000) >> 8;
- wei8_7 = (zhong_32 & 0xff0000) << 8;
- wei8_8 = (gao_32 & 0xff00) >> 8;
- wei8_9 = (gao_32 & 0xff) << 8;
- wei8_a = (gao_32 & 0xff000000) >> 8;
- wei8_b = (gao_32 & 0xff0000) << 8;
- ID[0] = wei8_0 | wei8_1 | wei8_2 | wei8_3;
- ID[1] = wei8_4 | wei8_5 | wei8_6 | wei8_7;
- ID[2] = wei8_8 | wei8_9 | wei8_a | wei8_b;
- wei8_1 = wei8_1 >> 8;
- wei8_2 = wei8_2 >> 16;
- wei8_3 = wei8_3 >> 24;
- wei8_5 = wei8_5 >> 8;
- wei8_6 = wei8_6 >> 16;
- wei8_7 = wei8_7 >> 24;
- wei8_9 = wei8_9 >> 8;
- wei8_a = wei8_a >> 16;
- wei8_b = wei8_b >> 24;
- di_32 = wei8_0 + wei8_1 + wei8_2 + wei8_3 + wei8_4 + wei8_5 + wei8_6 + wei8_7 + wei8_8 + wei8_9 + wei8_a + wei8_b;//每次读一个8位ID号累加
- zhong_32 = di_32 & 0x3ff; //提取低10位
- gao_32 = wei8_0 + wei8_b; //ID最低低8位+ID最高高8位
- di_32 = gao_32 + zhong_32; //ID最高位8位+ID最低8位+累加结果提取的10位
- ID[25840] = zhong_32;
- ID[25844] = di_32;
- for (int i = 0; i < 8; i = i + 1){
- mima[i] = ID[di_32 << 2];
- di_32 = (zhong_32 + di_32) & 0x3ff;
- }
- printf("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X \n",mima[0],mima[1],mima[2],mima[3],mima[4],mima[5],mima[6],mima[7]);
-
-
-
-
-
-
- }
-
复制代码
作者这个验证密码的漏洞比较大,静态分析都能看出来,要是有硬件插上JLINK一条命令就能定位,我前几年前研究过一段时间逆向,这种简单序列号保护价格可能100就有人做,他们就是把反汇编的代码放到KEIL里面重新编译然后软件仿真,估计某鱼上的就是花钱雇别人破解了卖钱而不放出来共享。
总之越用库函数和操作系统越容易被别人分析,只要做个签名文件反汇编后就直接出来函数名字了,就是不出来函数名字函数的排列也都和开发的时候一样,要是会用库开发STM32再去看别人用库写的程序反汇编后的就非常容易了,写程序的时候多费点力气别人看的时候一样也多费力气。 |
|