逆向小白之解决Focusky的离线登录问题
逆向小白之解决Focusky的离线登录问题
- 前言
- 一、初步思路
- 二、逆向尝试
- 1.初探
- 2.再探
- 3.三探
- 4.初捷
- 5.试手
- 6.再战
- 总结
前言
Focusky是一款非常优秀的演示制作工具,类似于Prezi,但功能更强大,对中文的支持更好。所以已经成了我做演示的第一选择,但有一个问题一直困扰我:公司使用的内部网络是不能连接到互联网的,而Focusky的导出等功能必须要登录才能使用,这就给我的讲义的分享造成了障碍。培训部门一直要求我把讲义分享出来,我每次发个PDF稿过去,结果都被批评为不愿分享。于是就想找个办法解决一下这个问题。
提示:以下内容仅供技术学习参考,请支持优质国产正版软件。
一、初步思路
最开始想到的思路是抓包分析,然后在内网上搭一个服务模拟响应,从而解决内网登陆问题,但是想想觉得这个方案难以实现,内网管理太严格,不可能随便让你架个服务的,还要修改DNS之类,在本机搭也很麻烦。(其实还是自己不太会 _)
于是决定还是逆向破解一下好了,把需要登录验证的地方绕开就好了呀。于是按这个思路开动。
二、逆向尝试
1.初探
先祭出x64dbg,准备对Focusky.exe 和 fs.exe进行跟踪,跟了好一会才发现不太对劲,搞了半天fs.exe不是正常的可执行文件。仔细观察了一番,发现了Adobe AIR的文件夹,原来这是用Adobe AIR技术开发的ActionScript3应用,就是俗称Flash的东东。
查看了fs.exe的文件头,发现了CWS的字样,这不就是swf文件么。看样子要用到SWF逆向了。
2.再探
SWF逆向对我这个小白来说也是新东西,当然是先搜啊搜啊的呀,下了不少所谓的各种工具,最后发现还是JPEXS Free Flash Decompiler 最管用。这个软件很良心,完全开源,功能强劲。
把fs.exe后缀改成swf,用FFDec打开,果然是swf的喔。但是跟想象中不一样的,没有发现什么资源和代码,只有一个DefineBinaryData和一些少量的脚本。
后来在反编译的脚本里看到:
private function init() : void{context = new LoaderContext();context.allowCodeImport = true;loader = new Loader();loader.contentLoaderInfo.addEventListener("complete",onComplete);loader.contentLoaderInfo.addEventListener("ioError",onError);loader.loadBytes(new FocuskyAirContentData(),context);}
果然又嵌套了一层。
3.三探
于是把DefineBinaryData导出成一个swf文件再打开,这下一切都出现了。脚本和资源都一目了然了。
这样很快就可以找到导出EXE的PublishWindow的脚本位置,可以找到几个判断的地方,比如:
对应的P-Code是:
这时只要点击edit p-code按钮就可以对这个p-code修改了,改成iffalse ofs0059就可以实现不用登陆也可以了。
我以为只要保存这个改过的SWF文件,然后导入fs.exe(实际也是swf文件)就应该可以了。事实证明我太天真了,做完这些,再启动Focusky就启动不了啊。囧
不知为什么会这样,难道也有什么自校验之类的?还是FFDec修改保存的SWF文件有错误?总之该怎么办呢?
4.初捷
后来就想啊,这些文件不是都要加载到内存来执行的么,改文件不行那改内存行不行呢?试试呗
又祭出了x64dbg,加载后在内存中搜索对应的P-Code的hexdata
找到了一个唯一的地址,把修改后的P-code代码替换,这里只改一个字节就行了。
然后再运行试一下,奏效!不再提示需要登陆了!
当然,还不是很完美,因为会弹出要升级的窗口。不过这个思路已经通了,只要再找到类似的判断点改掉就行了。
很快内存中需要修改的地方就都就位了,接下来就是要考虑怎么打这个内存补丁了,毕竟不能每次都祭出x64dbg么,还是需要简单点才好啊。
5.试手
打内存补丁我只会一种方法,那就是用Dll劫持。试了一下version.dll,果然可以利用。于是用上Aheadlib,打开VS,开始写代码呀。
与固定内存地址的打补丁稍有区别的是,由于每次运行内存中这个SWF文件的加载地址都是变化的,所以需要先搜索指定的特征码,找到后再改。特征码当然就是P-Code对应的hexdata了,查找算法本来想试一试自己实现一下sunday的算法,不过后来发现了一个更简单的方法。
这个代码段所在的内存区域的大小是固定的,虽然地址每次都变,但大小一直不变。并且需要修改的地方相对于这个区域的偏移是固定的。这样就只需要搜索这个大小的内存区域,属性为PRV、RW的就可以直接打补丁了。
以下是部分代码:
DWORD WINAPI PatchThread()
{DWORD dwProcessId;dwProcessId = GetCurrentProcessId();HANDLE hProcess;hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId);ULONGLONG dwAddrStart = 0x0;ULONGLONG dwAddrEnd = 0x7FFFFFFFFFFF;ULONGLONG dwAddrCur = dwAddrStart;ULONGLONG dwOffset = 0x3409F4; MEMORY_BASIC_INFORMATION mbi;memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION));while(true){dwAddrCur = dwAddrStart;while(dwAddrCur<dwAddrEnd){if (VirtualQueryEx(hProcess, (LPCVOID)dwAddrCur, &mbi, sizeof(mbi)) > 0){if (MEM_COMMIT == mbi.State && MEM_PRIVATE == mbi.Type && PAGE_READWRITE == mbi.Protect && mbi.RegionSize == 0x17B0000//the region size that include the code to patch){//find it, do patchULONGLONG AddrPatch;AddrPatch = (ULONGLONG)mbi.BaseAddress+dwOffset;if(CheckTheMem(){DoPatch();Debug("Patch is ok! \n");return 0;}return 0;}else{dwAddrCur += mbi.RegionSize ;}}else{dwAddrCur=dwAddrStart;Debug("VirtualQueryEx error:%d",GetLastError());}}Debug("All memory is checked. \n") ;Sleep(200);}return 0;
}
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{if (dwReason == DLL_PROCESS_ATTACH){DisableThreadLibraryCalls(hModule);CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PatchThread,NULL,0,NULL);}else if (dwReason == DLL_PROCESS_DETACH){}return TRUE;
}
很快这个用于打补丁的version.dll就写好了,放到Focusky的目录,试一下。正常启动,试着导出exe,不会提示需要登陆了,终于可以离线也可导出EXE了。成功!
6.再战
本来到这里我的初始目标已经实现了,解决了Focusky的离线使用问题。但是,呵呵,人都是有点好奇心的么。我就想啊,我能不能干脆让它登录好了,就是离线也能识别成登录状态,这样其他需要登录的功能不是也能使用了不是么。
于是仔细琢磨了一下,发现好像是可以实现的啊,只要把login的脚本改动一下,把需要联网获取的用户状态变成本地获取不就可以了么。
于是就开始动手实践了,当然过程比较漫长啦。毕竟我对ActionScript一点都不熟,再加上没办法直接写AS代码,而是需要写P-Code的代码,就是哪些Push,setlocal 的东西,所以还是花费了一定的时间。最后的用户登录代码大概改成类似这个样子:
public function login(u:String, p:String) : void{_logined = true;var file:File = File.applicationDirectory.resolvePath("user.xml");stream = new FileStream();stream.open(file,"read");data= new XML(stream.readUTFBytes(stream.bytesAvailable));readData(data);stream.close();Global.focusky.gSignalManager.signaled("SIGIN_IN_SUCCESS",this);}
当然这是用AS3代码示意的,实际是一堆类似下面的东西:
getlocal_0pushscopenewactivationdupsetlocal_3pushscopegetlocal_0getlocal_3swapsetslot 3findproperty Qname(ProtectedNamespace("com.wonderidea.focusky.air.user:User"),"_logined")swap
user.xml是一个XML格式的文本,这个文本里面包含了用户的基本信息,格式当然是抓的我自己的登录用户信息。示例如下:
<ID>4582165</ID><Email>master@focusky.com</Email><userName>master</userName>…………
这些修改还是一样通过version.dll来打内存补丁。最后的结果也是不错的,可以保持和正常联网登录一样的效果。当然那些需要联网使用的资源是用不了的。
总结
整个解决离线登录问题的过程还是很有意思的,第一次接触了ActionScript,感觉这还真是个好东东。只是已经很小众了,有点可惜。
这种打补丁的方式有一个不稳定的弊端,那就是有可能你打补丁的修改和原程序的读取同时发生,这时就会出错了,程序表现得很怪异。所以我通常需要把Focusky的自动登录关掉,然后把打补丁的时间延后到程序稳定启动后。在我的机器上是延后了500ms左右。这样基本上算是比较稳定。
最后,本文只为解决自己使用的痛点。请大家支持国产优质软件。
写作不易,如果觉得不错的,请关注评论一下。
逆向小白之解决Focusky的离线登录问题相关推荐
- 【JS 逆向百例】HN某服务网登录逆向,验证码形同虚设
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 文章目录 声明 逆向目标 ...
- 解决 MariaDB无密码就可以登录的问题
解决 MariaDB无密码就可以登录的问题 参考文章: (1)解决 MariaDB无密码就可以登录的问题 (2)https://www.cnblogs.com/Dicky-Zhang/p/800058 ...
- shiro解决一个账号异地登录的问题
shiro解决一个账号异地登录的问题 参考文章: (1)shiro解决一个账号异地登录的问题 (2)https://www.cnblogs.com/zeussbook/p/10882426.html ...
- 计算机用户停用无法登录,电脑开机无法登录提示您的账户已被停用如何解决。 如何解决电脑开机无法登录提示您的账户已被停用的问题。...
今天给大家带来电脑开机无法登录提示您的账户已被停用如何解决.,如何解决电脑开机无法登录提示您的账户已被停用的问题.,让您轻松解决问题. 最近有用户在电脑开机登录启动界面后提示"您的账户已被停 ...
- oracle的em能干什么,转载 解决Oracle的EM登录
转载 解决Oracle的EM登录 (2011-03-13 20:53:39) 标签: 杂谈 这几天解决了EM无法登录的问题,顺便也把j数据库程序中常出现的ORA_12518错误解决了,有必要总结一下, ...
- 【JS 逆向百例】37网游登录接口参数逆向
文章目录 声明 逆向目标 逆向过程 抓包分析 参数逆向 完整代码 37_encrypt.js 37_login.py 声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切 ...
- 【JS 逆向百例】当乐网登录接口参数逆向
文章目录 声明 逆向目标 逆向过程 抓包分析 参数逆向 完整代码 d_cn_encrypt.js d_cn_login.py 声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产 ...
- centos mysql无法登录,解决centos下MySQL登录1045问题
由于需要在centos下部署整个应用,自然少不了对数据库的操作.但很多人可能会遇到一些问题,比如创建用户成功,但是却无法登录. 无法登陆一般就两个原因.第一,远程访问端口没开,第二个原因就是密码错误了 ...
- 快速解决MariaDB无密码就可以登录的问题
快速解决MariaDB无密码就可以登录的问题 参考文章: (1)快速解决MariaDB无密码就可以登录的问题 (2)https://www.cnblogs.com/coffee_cn/p/101075 ...
最新文章
- 深度学习核心技术精讲100篇(十八)-巨量数据下美团是如何实现数据治理的?
- 在安装one_gadget遇到 one_gadget requires Ruby version >= 2.4. 的问题解决
- GitHub使用方法
- C#(4) implicit explicit
- zlib.h: 没有那个文件或目录
- c语言函数实际参数,C语言:函数声明与定义的参数不一致问题,后果可能很严重哦!!!!!...
- Android 系统(182)---Android.mk的用法和基础 amp;amp; m、mm、mmm编译命令
- 7.1.21 jQuery 的 Post请求
- 【转】你有这么一个人么
- spark 窗口函数(Window)实战详解
- vue启动报错error:cannot find module 'xxx'异常解决方法
- 1.6 CPU性能公式
- 现代交换原理——时间接线器
- c语言税务信息申报系统,四川税务网上申报系统下载
- 在Mac电脑的状态栏右上角显示自己的名字
- Games104现代游戏引擎入门-lecture12游戏引擎的粒子和声效系统
- 2018年前端年度工作总结
- python matplotlib 绘制K线图(蜡烛图)
- 【django】Windows下安装Redis
- 苹果震撼发布首款头显,搭配强悍Mac和iOS 17等全新产品,价值25000元!