csdn 样本9 blackbox 后2个加密字符的生成还原

前5个加密字符还原, 请看龙哥的文章

SO逆向入门实战教程九——blackbox
https://blog.csdn.net/qq_38851536/article/details/118115569

打开ida, 从sub_3B3C方法继续向下分析


1.png

我们一步一步看:

首先是v19的赋值

uint8x8_t v19; // d16 v19.n64_u32[1] = *(_DWORD *)"6789BCDFGHJKRTVWMNPQ567";

uint8x8_t 的结构体如下:

这里用到了 ARM NEON 编程
https://www.cnblogs.com/xylc/p/5410517.html

2.png

DCD 4个字节

DCW 2个字节

DCB 1个字节

DCQ 8个字节

// v35就是前5个加密字节 v19.n64_u32[0] = *(_DWORD *)&v35[1];

这一步将上面得到的后4个字节的加密值赋值给 n64_u32[0]

就是上边的CD2D

备注: CD2D 是从上一部分内容获取的, 请查看前半部分的内容
https://blog.csdn.net/qq_38851536/article/details/118115569

uint32x4_t v34; // [sp+20h] [bp-168h] BYREF //寄存器中的每个元素的长度都扩展为原来的两倍,u8扩展为u16 v34 = vmovl_u16((uint16x4_t)vmovl_u8(v19).n128_u64[0]);

分为以下4步:

  1. vmovl_u8对读取的uint8x8进行宽度扩展

vmovl_u8() 将uint8x8_t --> uint16x8_t

这句的作用是 //convert to 16-bit and move to 128-bit reg

CD2D 由原来的每个字符一个字节, 变成一个字符2个字节, 高位补0

  1. 然后取前n128_u64[0], 即取前64位数据

.n128_u64[0]”这个地方,根据IDA的解析规则,这代表一个128位的数据只取前64位,如果是“.n128_u64[1]”的话就是取后64位

  1. 然后 使用(uint16x4_t) 强转成 uint16x4_t 类型

这句的作用是 //get low 64 bit and move them to 64-bit reg

  1. 最后 vmovl_u16 对读取的uint16x4进行宽度扩展

vmovl_u16() 将uint16x4_t --> uint32x4_t

CD2D 由原来的每个字符2个字节, 变成一个字符4个字节, 高位补0

参考文档:

然后将拓展后的数据传入 sub_194C() 方法

在unidbg debugger 传到sub_194C方法是这样的


3.png

分析 sub_194C()


4.png
5.png

看上去调用了很多方法, 其实也没有什么 直接用java还原即可

下面放出代码:

public static int[] sub_194C(int[] a1) { int v1; int v3; int v4; int v5; int v6; int v7; int v8; int v9; int v18; int v23; int v24; int v22; int v21; int v20; int v19; int v10; int v11; int v12; int v13; int v14; int v15; int v16; v1 = a1[0]; v3 = sub_191E(v1); v4 = a1[1]; v24 = v3; v5 = (2 * v4) ^ 0x1B; if ( (v4 & 0x80) == 0 ){ v5 = 2 * v4; } v18 = v5 ^ v4; v23 = sub_18F8(v4); v6 = a1[2]; v22 = sub_18D4(v6); v7 = a1[3]; v21 = sub_191E(v4); v20 = sub_18F8(v6); v19 = sub_18D4(v7); v8 = v18 ^ sub_18D4(v1); v9 = v8 ^ sub_191E(v6); v10 = v9 ^ sub_18F8(v7); v11 = sub_18F8(v1); v12 = sub_18D4(v4); v13 = sub_191E(v7); a1[2] = v10 & 0xff; v14 = (2 * v1) ^ 0x1B; if ( (v1 & 0x80) == 0 ){ v14 = 2 * v1; } a1[1] = (v14 ^ v1 ^ v21 ^ v20 ^ v19) & 0xff; v15 = (2 * v7) ^ 0x1B; if ( (v7 & 0x80) == 0 ){ v15 = 2 * v7; } a1[0] = (v15 ^ v24 ^ v23 ^ v22 ^ v7) & 0xff; v16 = (2 * v6) ^ 0x1B; if ( (v6 & 0x80) == 0 ){ v16 = 2 * v6; } a1[3] = (v13 ^ v16 ^ v6 ^ v11 ^ v12) & 0xff; return a1; } public static int sub_191E(int a1) { boolean v2; int v3; int v4; v2 = (a1 & 0x80) != 0; v3 = (2 * a1) ^ 0x1b; if(!v2){ v3 = 2 * a1; } v4 = v3 ^ a1 ^ sub_18F8(a1); return sub_18D4(a1) ^ v4; } public static int sub_18F8(int a1) { int v1; int v2; v1 = (2 * a1) ^ 0x1b; if((a1 & 0x80) == 0){ v1 = 2 * a1; } v2 = (2 * v1) ^ 0x1b; if((v1 & 0x80) == 0){ v2 = 2 * v1; } return sub_18D4(v2 ^ v1); } public static int sub_18D4(int a1) { int v1; int v2; v1 = (2 * a1) ^ 0x1b; if((a1 & 0x80) == 0){ v1 = 2 * a1; } v2 = (2 * v1) ^ 0x1b; if((v1 & 0x80) == 0){ v2 = 2 * v1; } return v2 ^ v1; }

这里要注意的是:

算出来的数只取 低8位, 这个是通过调试知道的

调用sub_194C方法前:

6.png

CD2D

调用sub_194C方法后:

7.png

继续向下分析:

调用了sub_3864 方法

8.png

因为参数a2固定是100, 其实是调用了sub_37A4方法

9.png

sub_37A4 方法前面实现过了

继续向下走:

10.png

查看汇编流发现, sub_37A4 计算的结果还做了 乘法和减法的操作

11.png

对应的java代码:

传入参数是sub_194C的返回值

public static String getLast2(int[] v25){ // int[] v25 = new int[]{0x58,0xEB,0x45,0xF6}; int v26 = 0; int v28; int v29; String v29Str; for ( int i = 0; i != 4; ++i ) { v28 = v25[i]; v26 += v28; } System.out.println(v26); // 算出ida中 sprintf的v29, 这一步要看汇编 int a2 = 100; v29 = v26 - sub_37A4(v26, a2) * a2; // System.out.println(Integer.toHexString(v29)); // 处理v29 if (v29 > 100){ v29 = v29 % 100; } if (v29 < 10){ v29Str = "0" + v29; }else{ v29Str = "" + v29; } return v29Str; }

至此算法还原完成

下面验证算法

对比unidbg调用so生成的加密值和还原算法的加密值, 看是否相等

public static void main(String[] args) throws Exception { // 打印详细日志 // Logger.getLogger("com.github.unidbg.linux.ARM32SyscallHandler").setLevel(Level.DEBUG); // Logger.getLogger("com.github.unidbg.unix.UnixSyscallHandler").setLevel(Level.DEBUG); // Logger.getLogger("com.github.unidbg.AbstractEmulator").setLevel(Level.DEBUG); // Logger.getLogger("com.github.unidbg.linux.android.dvm.DalvikVM").setLevel(Level.DEBUG); // Logger.getLogger("com.github.unidbg.linux.android.dvm.BaseVM").setLevel(Level.DEBUG); // Logger.getLogger("com.github.unidbg.linux.android.dvm").setLevel(Level.DEBUG); // PrintStream out = null; CrackBlackBox obj = new CrackBlackBox(); // 加密的key的明文 String keyText = "r0env"; for(int i = 0; i<10000; i += 1){ double d = Math.random(); int temp = (int)(d*1000000); if(! obj.callEncode(temp, keyText).equals(utils.encode(temp, keyText))){ System.out.println("两种方法的加密值不一样!!!!!!!!!!!!!!"); }; } obj.destroy(); }

日志如下:

unidbg调用so生成的加密值是: G7WJW18 [0, 0, 0, 0, 0, 3, -44, 7] hmacsha1加密值: 4e83863c0704078a26eF1Fb36b23905685ed2Fa4 索引值是: 4 前5个加密字节是: G7WJW 518 后2个加密字节是: 18 本地还原方法的最终加密值是: G7WJW18 unidbg调用so生成的加密值是: QRDH338 [0, 0, 0, 0, 0, 11, 25, 82] hmacsha1加密值: 1875d19268Fc156d09e0b4726e5bedFFbFca37ca 索引值是: 10 前5个加密字节是: QRDH3 638 后2个加密字节是: 38 本地还原方法的最终加密值是: QRDH338 unidbg调用so生成的加密值是: WXHGV98 [0, 0, 0, 0, 0, 8, 28, -87] hmacsha1加密值: 6d78a4050698aa9Fb20764321ad0b23bbFF53a0c 索引值是: 12 前5个加密字节是: WXHGV 398 后2个加密字节是: 98 本地还原方法的最终加密值是: WXHGV98 ....

算法验证成功

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容