逆向小白之解决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的离线登录问题相关推荐

  1. 【JS 逆向百例】HN某服务网登录逆向,验证码形同虚设

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 文章目录 声明 逆向目标 ...

  2. 解决 MariaDB无密码就可以登录的问题

    解决 MariaDB无密码就可以登录的问题 参考文章: (1)解决 MariaDB无密码就可以登录的问题 (2)https://www.cnblogs.com/Dicky-Zhang/p/800058 ...

  3. shiro解决一个账号异地登录的问题

    shiro解决一个账号异地登录的问题 参考文章: (1)shiro解决一个账号异地登录的问题 (2)https://www.cnblogs.com/zeussbook/p/10882426.html ...

  4. 计算机用户停用无法登录,电脑开机无法登录提示您的账户已被停用如何解决。 如何解决电脑开机无法登录提示您的账户已被停用的问题。...

    今天给大家带来电脑开机无法登录提示您的账户已被停用如何解决.,如何解决电脑开机无法登录提示您的账户已被停用的问题.,让您轻松解决问题. 最近有用户在电脑开机登录启动界面后提示"您的账户已被停 ...

  5. oracle的em能干什么,转载 解决Oracle的EM登录

    转载 解决Oracle的EM登录 (2011-03-13 20:53:39) 标签: 杂谈 这几天解决了EM无法登录的问题,顺便也把j数据库程序中常出现的ORA_12518错误解决了,有必要总结一下, ...

  6. 【JS 逆向百例】37网游登录接口参数逆向

    文章目录 声明 逆向目标 逆向过程 抓包分析 参数逆向 完整代码 37_encrypt.js 37_login.py 声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切 ...

  7. 【JS 逆向百例】当乐网登录接口参数逆向

    文章目录 声明 逆向目标 逆向过程 抓包分析 参数逆向 完整代码 d_cn_encrypt.js d_cn_login.py 声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产 ...

  8. centos mysql无法登录,解决centos下MySQL登录1045问题

    由于需要在centos下部署整个应用,自然少不了对数据库的操作.但很多人可能会遇到一些问题,比如创建用户成功,但是却无法登录. 无法登陆一般就两个原因.第一,远程访问端口没开,第二个原因就是密码错误了 ...

  9. 快速解决MariaDB无密码就可以登录的问题

    快速解决MariaDB无密码就可以登录的问题 参考文章: (1)快速解决MariaDB无密码就可以登录的问题 (2)https://www.cnblogs.com/coffee_cn/p/101075 ...

最新文章

  1. 深度学习核心技术精讲100篇(十八)-巨量数据下美团是如何实现数据治理的?
  2. 在安装one_gadget遇到 one_gadget requires Ruby version >= 2.4. 的问题解决
  3. GitHub使用方法
  4. C#(4) implicit explicit
  5. zlib.h: 没有那个文件或目录
  6. c语言函数实际参数,C语言:函数声明与定义的参数不一致问题,后果可能很严重哦!!!!!...
  7. Android 系统(182)---Android.mk的用法和基础 amp;amp; m、mm、mmm编译命令
  8. 7.1.21 jQuery 的 Post请求
  9. 【转】你有这么一个人么
  10. spark 窗口函数(Window)实战详解
  11. vue启动报错error:cannot find module 'xxx'异常解决方法
  12. 1.6 CPU性能公式
  13. 现代交换原理——时间接线器
  14. c语言税务信息申报系统,四川税务网上申报系统下载
  15. 在Mac电脑的状态栏右上角显示自己的名字
  16. Games104现代游戏引擎入门-lecture12游戏引擎的粒子和声效系统
  17. 2018年前端年度工作总结
  18. python matplotlib 绘制K线图(蜡烛图)
  19. 【django】Windows下安装Redis
  20. 苹果震撼发布首款头显,搭配强悍Mac和iOS 17等全新产品,价值25000元!

热门文章

  1. Quicker:Windows 办公效率神器 | 初学者必备(一)
  2. 2022全球数商大会顺利举行,合合信息旗下启信宝斩获年度数据产品奖
  3. Python数字货币量化初探
  4. 聊聊固态硬盘1--人生头两块SSD
  5. coreldraw x4怎么会蓝屏_精简-系统爱好者
  6. 智禾教育:根据淘宝退款规则要求,淘宝卖家该如何处理退款申请
  7. 击败一半参赛程序员,DeepMind 重磅推出 AlphaCode
  8. 程序员的十大经典口头禅你知道吗
  9. FreeSwitch mod_dptools: playback
  10. 数据库中的悲观锁和乐观锁