吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|青海快3规律 www.yvi63.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12012|回复: 105
上一主题 下一主题

排列3和值尾数走势图: [决赛第二题] 腾讯游戏安全技术竞赛 - 决赛第二题进阶版 writeup

  [复制链接]
跳转到指定楼层
楼主
发表于 2018-5-16 18:29 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 879154904 于 2018-5-16 23:00 编辑


收到官方邀请写write-up, 还是蛮开心的,
本文写的尽量详细一些, 有不懂的可以留言大家一起讨论学习:lol

青海快3规律 www.yvi63.cn 第一题实在过于简单,一个OpenGL的3D程序, 只要CE修改camera坐标到右上角就能看到flag了
这里分析第二题的进阶版

第一关

x32dbg载入, 各种关键点下断, 程序依赖了两个dll, 入口全部下断再说,
果然点击第一关的验证按钮, 断在了tmgs.dll的maln函数
其实这个程序分析的时候大量时间花在了lua函数的识别上,
1.png
function_verify核心如下:
2.png
function_verify里面是调用lua脚本进行一个check, 这里是对照lua源码一个个标记的函数名, 花费了很多时间
同时根据上图可以发现lua脚本在luaOpcode里面,将lua的luaOpcode导出使用luadec反编译可以得出验证逻辑,
标准版到这里基本就结束了,但是进阶版官方做了一些小动作,lua的op_mode被做了一些处理

通过搜索关键词”must be a number” 定位到luaV_execute函数,此处通过和lua源代码对比发现opcode做了大量改动,通过逐一对比47个lua指令switch的大量代码,人肉得出还原表 写出函数 de_op_codes

int de_op_codes(int en) {
    int r = 0;
    switch (en)
    {
    case 0:
        return 0xfe;
    case 6u:
    case 7u:
    case 0x16u:
    case 0x1Bu:
        return 0;
    case 0x22u:
    case 0x28u:
    case 0x29u:
    case 0x3Cu:
        return 1;
    case 0x3Eu:
        return 2;
    case 0x3Bu:
        return 3;
    case 0x12u:
        return 4;
    case 8u:
    case 0x11u:
    case 0x17u:
    case 0x36u:
        return 5;
    case 2u:
        return 6;
    case 0xDu:
        return 7;
    case 0x1Au:
        return 8;
    case 1u:
        return 9;
    case 0x1Du:
        return 0xA;
    case 0x1Fu:
        return 0xB;
    case 0xEu:
        return 0xC;
    case 0x31u:
        return 0xD;
    case 0x2Fu:
        return 0xE;
    case 0x1Eu:
        return 0xF;
    case 0x15u:
        return 0x10;
    case 0x3Au:
        return 0x11;
    case 0x13u:
        return 0x12;
    case 0x24u:
        return 0x13;
    case 0x2Bu:
        return 0x14;
    case 0x1Cu:
        return 0x15;
    case 0x2Du:
        return 0x16;
    case 0x19u:
        return 0x17;
    case 0x3Fu:
        return 0x18;
    case 0x18u:
        return 0x19;
    case 0x33u:
        return 0x1A;
    case 0xFu:
        return  0x1B;
    case 0x34u:
        return 0x1C;
    case 0x20u:
        return 0x1D;
    case 5u:
    case 9u:
    case 0xAu:
    case 0x25u:
        return 0x1E;
    case 0x30u:
        return 0x1F;
    case 0x26u:
        return 0x20;
    case 0x35u:
        return 0x21;
    case 0x38:
        return 0x22;
    case 0x2Au:
        return 0x23;
    case 0x23u:
    case 0x37u:
    case 0x39u:
    case 0x3Du:
        return 0x24;
    case 0x27u:
        return 0x25;
    case 4u:
        return 0x26;
    case 0x2Cu:
        return 0x27;
    case 0x32u:
        return 0x28;
    case 0x21u:
        return 0x29;
    case 0x03:
        return 0x2A;
    case 0xCu:
        return 0x2B;
    case 0x2Eu:
        return 0x2C;
    case 0x14u:
        return 0x2D;
    case 0xB:
        return 0x2E;
    case 0x10:
        return 46;
    default:
        return 0;
    }
}

将此函数写入 luadec的GET_OPCODE宏指令中,重新编译运行luadec即可还原出lua, 关键部分如下
3.png

可以看到程序里面通过rc4做了验证,由于rc4是对称加密算法,因此只需要对dst的密文加密一次就可以得到通关密码
4.png

第二关

通过在UE引擎关键地方下断点,发现第二问处理逻辑主要在UE引擎内部,
UE4引擎事件分发如下, 下文函数都会标记详细的偏移

#define RESULT_DECL = void*const Z_Param__Result

// UObject::ProcessInternal_62E860
void UObject::ProcessInternal( UObject* Context, FFrame& Stack, RESULT_DECL)
call eax

// UObject::execLet_632310
void UObject::execLet( UObject* Context, FFrame& Stack, RESULT_DECL)
call eax

// UObject::execContext_6319D0
void UObject::execContext( UObject* Context, FFrame& Stack, RESULT_DECL )
P_THIS->ProcessContextOpcode(Stack, RESULT_PARAM, /*bCanFailSilently=*/ false);

// UObject::ProcessContextOpcode_62E0B0  
void UObject::ProcessContextOpcode( FFrame& Stack, RESULT_DECL, bool bCanFailSilently )
call eax

// UObject::execFinalFunction_631D50
void UObject::execFinalFunction( UObject* Context, FFrame& Stack, RESULT_DECL )
P_THIS->CallFunction( Stack, RESULT_PARAM, (UFunction*)Stack.ReadObject() );

// UObject::CallFunction_628860
void UObject::CallFunction( FFrame& Stack, RESULT_DECL, UFunction* Function )
Function->Invoke(this, Stack, RESULT_PARAM);

// Function_Invoke_641570
void UFunction::Invoke(UObject* Obj, FFrame& Stack, RESULT_DECL)
return (*Func)(Obj, Stack, RESULT_PARAM);

一个完整流程:

-> Function_Invoke_641570 
-> UObject::ProcessInternal_62E860 
-> UObject::CallFunction_628860 
-> UObject::ProcessInternal_62E860 
-> UObject::execLet_632310
-> UObject::execContext_6319D0 
-> UObject::ProcessContextOpcode_62E0B0 
-> sub_631DF0  
-> UObject::execFinalFunction_631D50 
-> UObject::CallFunction_628860 
-> Function_Invoke_641570

核心函数在 Function_Invoke_641570 里面, 通过对此函数进行下断点可以记录到调用了以下几个函数, 下面给出函数地址和具体功能

Function: 16D6860 check2_str_to_FString_846860
Function: 16CAF10 check2_GetUnicodeStringLength_83AF10
Function: 16D6860 check2_str_to_FString_846860
Function: 139B530 check2_md5_50B530
Function: 16CAF10 check2_GetUnicodeStringLength_83AF10
... 此处省略N个无关函数
Function: 139B340 check2_get_a_md5_50B340 
# 内置了一个字符串, 获取内置字符串的md5
Function: 16D6860 check2_str_to_FString_846860
Function: 139B530 check2_md5_50B530
Function: 16C5C60 check2_main_835C60
Function: 50B420 fun_showmsg_50B420(&第二关:验证失败,请重试)
... 此处继续省略N个无关函数

在调用显示函数显示出通过失败的上一步, 就是核心判断函数check2_main_835C60。
再次向上,是check2_md5_50B530,这一步里面会将一个字符串计算md5。
check2_md5_50B530内部又调用check2_md5_calc_50A800进行真正的计算。
对·check2_md5_calc_50A800·下断点可以发现程序依次对

E0EA72E0E1C1BFFBC26E8B47AD9D809C
tencent_mobile_game+-999893888
输入的PASSWORD

这三个内容计算md5,
继续单步跟踪发现程序在check2_main_835C60里面对 第二次 和 第三次 字符串md5做对比, 那么key显而易见了, 就是第二次的字符串
第二次的字符串tencent_mobile_game+是写死在程序里面的
-999893888 是这里算出来的
2_1.png
2_2.png

本题主要考察UE4事件分发流程了, 当然如果什么都不懂的话直接IDA findcrypt在md5的地方下断也能做出来就是了...

第三关

算法导出

到了这一关, 点击按钮又顺利断下来了, 还是上次的dll, 进入了ths函数
3_1.png
可以看到是在ph2.dll里面进行的处理(基础版直接是sub_100363A0,和第一关类似的过程)
3_2.png
进入ph2.dll,依然是lua脚本,直接dump出bin变量的脚本,
可以看到脚本是头部有jt,是使用luajit生成的字节码,直接使用luajit-decomp进行反编译, 编译后代码:
3_3.png

check函数内生成了一个虚拟机, 执行虚拟机代码对输入的数据(plainBs)进行加密处理, 加密后和内置的(dstRes)进行比对
通过对虚拟机代码进行导出,导出工具以及导出的z3t_table.lua都已经放在附录,
虚拟机代码有18个指令, 分别为加减乘除判断跳转压栈出栈等,且采用了大数运算库
这里需要对虚拟机代码进行分析, 附录有我自己通过js自己重新实现的,
其实这里标准版和进阶版差不多了, 附录的代码里面附带了标准版的实现, 可以说进阶版除了数大一点(BigNumber😄), 其余的全是一样的

分析后如下:

算法分析

首先初始化一个b64字母表
3_4.png

然后对输入的数据进行分组,8个一组,前两个做以下运算, 生成8字节数据
3_5.png

对后6个的运算如下

InfInt x = (x2 * 256 + x1) + (x3 * 256 * 256) + 256 * 256 * 256 * (x5 * 256 + x4 + x6 * 256 * 256);
(实际上是 x1-x6分别为二进制8位排开)
a = savebyte + (x % 61454 * 256) 
b = (x % 54732) + ((x % 5136) % 256 * 256 * 256) 
c = (x % 25548) * 256 + ((x % 5136) >> 8) 

随后对a/b/c/(res2)生成4个字节目标数据, 一共3*4=12字节
3_6.png

逆向思路:

dstRes分组,每组8+12=20位,前8为计算出原有前2位,后12位计算出后6位

详细逆向过程:

前2位可以直接约束求解
3_7.png

后6位算法较为复杂, 且数据较大, 可以先化简分析
由于计算过程是

x = (x2 * 256 + x1) + (x3 * 256 * 256) + 256 * 256 * 256 * (x5 * 256 + x4 + x6 * 256 * 256)
a = savebyte + (x % 61454 * 256) 
b = (x % 54732) + ((x % 5136) % 256 * 256 * 256) 
c = (x % 25548) * 256 + ((x % 5136) >> 8) 

因此逆向过程为 abc已知, 求x(x1-x6可以通过x算出)
令R=savebyte
公式写为

R+(x%61454*256)=a,
(x%54732)+((x%5136)%256*256*256)=b,
(x%25548)*256+((x%5136)>>8)=c

化简:

x%61454 = (a-R) >> 8
x%54732 = b & 0xFFFF
x%5136  = ((b & 0xFF0000) >> 16)  +  ((c & 0xFF) << 8)
x%25548 = c >> 8

到这一步可以看出右边均是已知,转化为同余方程组,
由于m不互质,因此不可以使用孙子定理, 这就和这一题一样了
project euler problem 531

对于一个同余方程:

3_8.png

设g=gcd(n1,n2),可以得到若方程有解,则g|(a1−a2) 必成立;其逆否命题成立。

3_9.png

复杂度O(n2logn) 。因此此题中四组可以两两分组
x1 and x2 得到 x‘,x' and x3 得到 x'',x'' and x4 得到 answer

算出x之后,x1-x6可以这样算出
3_10.png

至此,三道题求解完毕
3_11.png

附录代码

https://github.com/Tai7sy/mtp_2018_write_up

免费评分

参与人数 42吾爱币 +38 热心值 +36 收起 理由
wscg + 1 + 1 我很赞同!
我是神金币 + 1 + 1 一脸懵逼的看完。
Aynamic + 1 + 1 鼓励转贴优秀软件安全工具和文档!
杀猪用牛刀 + 1 + 1 谢谢@Thanks!
ask1000 + 1 谢谢@Thanks!
黑夜渐暖 + 1 + 1 谢谢@Thanks!
林伟 + 1 + 1 热心回复!
楓楪-李 + 1 + 1 我很赞同!
阿尔卡伊达 + 1 + 1 热心回复!
weijin + 1 热心回复!
22222 + 1 + 1 热心回复!
YS123456 + 1 鼓励转贴优秀软件安全工具和文档!
埃特纳火山 + 1 + 1 懵逼树上懵逼果,懵逼树下你和我
↑帝↑ + 1 + 1 热心回复!
Sen + 1 + 1 看不懂看不懂
theSeven + 1 + 1 热心回复!
二逼159 + 1 + 1 热心回复!
Ravey + 1 + 1 谢谢@Thanks!
Lion-R + 1 腾讯游戏不会再花1分钱。
hhh1xx + 1 + 1 用心讨论,共获提升!
silvanevil + 1 + 1 热心回复!
Triad + 1 谢谢@Thanks!
tztt3033 + 1 + 1 用心讨论,共获提升!
xuwenyi + 1 + 1 谢谢@Thanks!
Lxai + 1 + 1 用心讨论,共获提升!
zhiyi1120 + 1 + 1 用心讨论,共获提升!
Ouyang520 + 1 + 1 热心回复!
sunnylds7 + 1 + 1 热心回复!
柿子i + 1 + 1 我很赞同!
特殊符号 + 1 懵逼树上懵逼果,懵逼树下你和我
Faithful丶o + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
SomnusXZY + 1 + 1 热心回复!
xi前 + 1 + 1 谢谢@Thanks!
zhaojunkai + 1 + 1 我很赞同!
hi566 + 1 用心讨论,共获提升!
基裏連科 + 1 + 1 用心讨论,共获提升!
羽落星寒 + 1 + 1 我很赞同!
zzzlucas + 1 + 1 谢谢@Thanks!
这是追求不是梦 + 1 + 1 热心回复!
C-ARan + 1 谢谢@Thanks!
很快再相见123 + 1 感谢分享
RuthenKi + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

推荐
发表于 2018-5-16 21:06 | 只看该作者
本帖最后由 ripples 于 2018-5-16 21:09 编辑
879154904 发表于 2018-5-16 20:15
文章里面说了啊
luajit-decomp,  github有 可以搜一下,  (反编译也是没有变量名的, 变量名是我自己修改 ...

谢谢,搜到了,刚看漏了,不好意思

(哎呀,看了下发现这个工具我搜到过,不过因为不是 Windows 没跑成……

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

推荐
 楼主| 发表于 2018-5-16 20:15 | 只看该作者 |楼主
ripples 发表于 2018-5-16 19:59
楼主 luajit 转 lua 用的什么工具啊,感觉看起来结果比我找的工具漂亮多了

文章里面说了啊
luajit-decomp,  github有 可以搜一下,  (反编译也是没有变量名的, 变量名是我自己修改的)

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

头像被屏蔽
板凳
发表于 2018-5-16 18:47 | 只看该作者

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

报纸
发表于 2018-5-16 18:51 | 只看该作者
前排围观

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

地板
发表于 2018-5-16 19:14 | 只看该作者
冷眸藐视 发表于 2018-5-16 18:47
还以为很难。??蠢慈ヌ谘队邢M?/blockquote>

大神历害...这样还不难!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

7#
发表于 2018-5-16 19:26 | 只看该作者
前排膜拜大神  话说我们论坛有没有暑假班

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

8#
发表于 2018-5-16 19:29 | 只看该作者
前来围观

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

9#
发表于 2018-5-16 19:59 | 只看该作者
楼主 luajit 转 lua 用的什么工具啊,感觉看起来结果比我找的工具漂亮多了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

10#
发表于 2018-5-16 21:07 | 只看该作者
前排膜拜大神,也学习一下!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则


免责声明:
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:[email protected]

快速回复 收藏帖子 返回列表 搜索

RSS订阅|手机版|小黑屋|联系我们|青海快3规律 ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2018-7-6 10:52

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 青海快3规律 返回列表
  • [大笑]阿Q都是这么说的。。。。。。 2018-08-15
  • 意料之中。美国若逼中国汇率升值,它自己会变成世界老二,所以只能直接动商品 2018-07-14
  • 肉毒梭菌感染相关新闻 2018-07-14
  • 马克思主义通过指导无产阶级革命建立起部分社会财富公有制而改变了人类历史发展进程,离开部分社会财富公有制的建立来谈“改变人类历史发展进程”纯粹是无稽之谈。 2018-07-13
  • 为迎香港回归,他用99天徒步走完京九线 2018-07-13
  • 别做梦了,醒醒吧。一个国家强大,教育是重要的。没有你说的那样美国妒忌心态。美国害怕的是中国不改革不开放,因为中国一旦做自己的企业,走自己的道路,对美国来说意味美 2018-07-12
  • 中国红旗9导弹相关新闻 2018-07-12
  • 写字楼起火 员工为保客户资料抱电脑主机逃下11楼 2018-07-11
  • 纪检监察机关加强扶贫领域监督执纪问责工作 2018-07-11
  • “十三五”规划出炉 古镇展望后五年发展蓝图 2018-07-11
  • 吃凉菜才是夏天的正经事 2018-07-10
  • 人民日报:中国经济稳步迈向高质量 2018-07-10
  • “亚洲第一海军”的蒙古国海军司令要管多少事儿?仨船俩炮六个兵 2018-07-10
  • 全新传祺GS4上市 祺云概念智慧SUV 2018-07-09
  • 暖心!高铁列车为他停靠三分钟 这一次没有人反对 2018-07-09