易语言程序分析笔记
易语言静态编译由于是静态地址,所以已经有工具可以分析了;但是非静态的因为是动态加载库,分析起来还是有点小麻烦的。这个笔记是我之前分析一个易样本时总结的,可能有些地方也不对,凑合看吧。要点易语言的入口函数特征各种函数的调用特征以及识别针对易语言程序的分析插件1、如何识别易语言程序一、查看文件信息右键-属性-详细信息二、查看资源文件Resource Hacker或其他可查看资源文件的工具
三、库文件易语言程序依赖于自实现的库(.fnr)执行,针对易语言的编译模式有静态编译、非静态编译和独立编译,如下图:编译:编译程序时,会将所有需要用到的库文件生成到同程序的目录下。
非静态编译:编译程序时,将所有用到的库文件写入到程序中,与程序合并,编译出来的文件只有程序本身。
独立编译:与静态编译相同之处是编译出来后只有程序本身,但运行程序时,会将所有用到的库文件写入到临时目录中,然后加载库文件。四、字符串特征由于易语言是自写的框架,类似于MFC,因此如果未处理编译后的程序,程序中将存在一些固定的字符串。
五、易语言标准入口
①静态编译静态编译是直接将库文件与程序合并。
②非静态编译该种编译模式会将库文件存放在程序中,在WinMain入口会获取读取自身的内容,然后释放出库文件随后加载库文件,并调用一个固定函数GetNewSock。最后调用函数进入该函数后,会看到call eax,eax为函数入口。
③黑月编译黑月编译器是网友针对易语言程序编写的一款编译器,他直接会优化掉前期的初始化代码,包括clr(c library runtime)初始化,直接进入到易语言的标准入口。
2、易语言的函数类型及特征易语言的函数大致分有三种,分别为窗体控件的消息函数、用户自定义函数、库函数和组件属性函数。
一、消息函数消息函数都是通过固定代码段调用,代码段定位流程如下:找到如图特征进入函数后找到最后一call 局部变量,该位置调用的就是消息函数
将函数对应到IDA中可直接定位到流程。找到 case 2008:二、用户自定义函数用户自定义的函数调用与通常的函数调用方式一致。
三、库函数库函数为易语言自写支持库里的函数,类似Windows的DLL文件。函数原型如下。E_FuncCallBack(2,参数一的值,参数一是否可忽略,参数一的类型,参数二的值,参数二是否可忽略,参数二的类型)该函数是一个变参函数,参数一为欲调用欲调用函数的参数个数,然后其余的以三个参数为一组表示参数的信息。忽略参数的值为布尔值,0表示不可以忽略,1表示可忽略;其参数类型可参考的值如下(可能不完整):
值类型
0x80000004文本型
0x80000101文本型
0x80000000通用型
0x80000002逻辑型
0x80000005字节集
0x80000006子程序指针
0x80000301数值型
0x80000601数值型
0x10001窗体
由于易语言的编译模式不同,库函数调用代码也会产生差异。接下来分别解释静态编译与非静态编译下,函数代码的差异。静态编译非静态编译非静态编译的程序,在调用库函数时不再通过静态地址的方式调用,而是通过传入库文件序号和欲调用对应函数的偏移到寄存器中,然后调用。库文件序号指的是库文件是程序中加载的第几个文件。序号从0开始,易语言程序在运行初期最先加载的库文件为该库文件,记加载序号为0;如果再加载一个库文件的话则加载新加载的库文件序号为1。对于调用krnln.fnr库文件的函数,易语言程序以隐式形式传递序号,因此在信息框函数调用的反汇编代码中并未看到传入0序号。常用库文件的函数偏移在附录中贴出。四、组件属性函数函数分为两种,一种是对组件的属性修改,另一种是组件的自带函数。属性修改参数一:父窗口参数二:子窗口参数三:属性下标参数四:未知,一般都为-0x1参数五:值自带函数调用与消息函数类型。参一:参数个数、参二:值,也就是父窗口ID、参三:ID、参四:参数类型因为控件存在于krnln.fnr库中,因此在非静态编译中,库函数序号也是隐式传递。部分组件ID也在附录中列出。3、易语言的基本数据类型一、字节集typdef struct 字节集{ int unkown; int length; char* bytes;};4、编译器:黑月程序入口为两个函数。进入第二个后可以看到如下代码特征。或者搜索到如下字符串。
5、易语言分析插件一、E-Debug(https://github.com/fjqisba/E-debug-plus)只能用来分析静态编译的程序。OD
IDA选择易语言反编译器IDA会自动识别由于的函数,并在工具栏新增易语言。
新增的项可以自动识别资源常量、窗体、消息函数(控件函数)。特征生成EDebug可以手动生成后缀为sig的易语言特征,打开配套工具。然后将易语言的支持库拖入即可,最后将生成的sig文件放置到对应分析工具的插件目录下。6、花指令易语言可以设置花指令来干扰程序的逆向分析。在工具栏的工具-系统配置的窗口中选择安全,可以设置花指令等级,默认为1。级别不同,花指令形式也不同。但是每一级别的花指令代码都是固定的,所以可以在IDA中使用脚本进行批处理处理,或者使用OD的插件去除花指令。输入要去除花指令的起始地址和地址段大小后,点击执行即可去除。
7、针对一些窗口跳转的破解易语言载入窗口的命令为载入(,,),窗体的类型为0x10001,因此可以通过搜索push 0x10001来找到该命令,或者有调用窗口函数的代码段来获取窗口ID。再将原始加载的窗口ID进行替换即可实现窗口跳转。搜索push 0x10001结果。断点放开后执行,直接能跳转到第二个窗口。8、附录一、支持库函数偏移系统核心支持库——krnln0x0:寻找文件0x2:相加0x9:新建索引0x58:取符号0x5C:取绝对值0x60:取整0x64:绝对取整0x68:四舍五入0x6C:求次方0x70:求平方根0x74:求正弦0x78:求余弦0x7C:求正切0x80:求反正切0x84:求自然对数0x88:求反对数0x8C:是否运算正确0x90:置随机数种子0x94:取随机数0xC0:位取反0xC4:位与0xC8:位或0xCC:位异或0x100:取命令行0x104:取运行目录0x108:取执行文件名0x10C:读环境变量0x110:写环境变量0x114:取所有发音0x118:取发音数目0x11C:取拼音0x124:取韵母0x128:发音比较0x12C:输入字比较0x130:取文本长度0x134:取文本左边0x138:取文本右边0x13C:取文本中间0x140:字符0x144:取代码0x148:寻找文本0x14C:倒找文本0x150:到大写0x154:到小写0x158:到全角0x15C:到半角0x160:到时间0x164:到数值0x168:到文本0x16C:删首空0x170:删尾空0x174:删首位空0x178:删全部空0x17C:文本替换0x180:子文本替换0x184:取空白文本0x188:取重复文本0x18C:文本比较0x190:分割文本0x194:取字节集长度0x198:到字节集0x19C:取字节集数据0x1A0:取字节集左边0x1A4:取字节集右边0x1A8:取字节集中间0x1AC:寻找字节集0x1B0:倒找字节集0x1B4:字节集替换0x1B8:子字节集替换0x1BC:取空白字节集0x1C0:去重复字节集0x1C4:分割字节集0x1C8:数值到大写0x1CC:数值到金额0x1D0:数值到格式文本0x1D4:取十六进制文本0x1D8:取八进制文本0x1DC:增减时间0x1E0:取时间间隔0x1E4:取某月天数0x1E8:时间到文本0x1EC:取时间部分0x1F0:取年份0x1F4:取月份0x1F8:取日0x1FC:取星期几0x200:取小时0x204:取分钟0x208:取秒0x20C:指定时间0x210:取现行时间0x214:置现行时间0x218:取磁盘总空间0x21C:取磁盘剩余空间0x220:取磁盘卷标0x224:置磁盘卷标0x228:改变驱动器0x22C:改变目录0x230:取当前目录0x234:创建目录0x238:删除目录0x23C:复制文件0x240:移动文件0x244:删除文件0x248:文件更名0x24C:文件是否存在0x254:取文件时间0x258:取文件尺寸0x25C:取文件属性0x260:置文件属性0x264:取临时文件名0x268:读入文件0x26C:写到文件0x270:打开文件0x274:打开内存文件0x278:关闭文件0x27C:关闭所有文件0x280:锁住文件0x284:解锁文件0x288:移动读写位置0x28C:移到文件首0x290:移到文件尾0x294:读入字节集0x298:写出字节集0x268:读入文件0x2A0:写出文本0x2A4:读入一行0x2A8:写文本行0x2AC:读入数据0x2B0:写出数据0x2B4:是否在文件尾0x2B8:取读写位置0x2BC:取文件长度0x2C0:运行0x2C4:取剪辑板文本0x2C8:置剪辑板文本0x2CC:剪辑板中可有文本0x2D0:清除剪辑板0x2D4:取屏幕宽度0x2D8:取屏幕高度0x2DC:取鼠标水平位置0x2E0:取鼠标垂直位置0x300:信息框0x304:鸣叫0x308:取启动时间0x320:载入0x330:是否已创建0x334:取数据类型尺寸0x35C:取窗口句柄0x540:是否支持多用户0x544:取错误码0x548:取错误信息0x54C:创建0x550:打开0x554:替换打开0x558:置当前库0x55C:取当前库0x560:关闭0x564:全部关闭0x568:取库文件名0x56C:是否已打开0x570:取记录数0x574:取创建时间0x578:取字段数0x57C:取字段名0x580:改字段名0x584:取字段类型0x588:取字段尺寸0x58C:新建索引0x590:置当前索引0x594:取当前索引0x598:更新索引0x59C:取索引数0x5A0:取索引名0x5A4:取索引字段0x5A8:置加锁重试时间0x5AC:锁住数据库0x5B0:解锁数据库0x5B4:锁住增删0x5B8:解增删锁0x5BC:锁住记录0x5C4:解锁记录0x5C8:全部解锁0x5CC:取平均值0x5D0:求和0x5D4:取最大值0x5D8:取最小值0x5DC:取最大时间0x5E0:计算数目0x5E4:复制结构0x5E8:复制记录0x5EC:计算排序0x5F0:排序0x5F4:分类计算0x5F8:添加0x5FC:加记录0x600:加空记录0x604:替换0x608:修改0x60C:删除0x610:是否已删除0x614:恢复删除0x618:彻底删除0x61C:清空0x620:读0x624:写0x628:读字段0x62C:写字段0x630:附加字节集0x634:附加备注0x638:索引查找0x63C:查找0x640:到首记录0x644:到尾记录0x648:跳过0x64C:取记录号0x650:跳到0x654:取标签0x658:记录是否存在0x65c:标签跳转0x660:首记录前0x664:尾记录后0x668:写出缓存0x66c:写出所有缓存0x670:编辑0x674:置等待鼠标0x678:恢复鼠标0x67C:延时0x688:插入字节集0x68C:插入文本0x690:插入文本行0x694:删除数据0x698:取文本注册项0x69C:取数值注册项0x6A0:取字节集注册项0x6A4:写注册项0x6A8:删除注册项0x6AC:注册项是否存在0x6C4:取硬盘特征字0x6F4:转换为主机名0x6F8:转换为IP地址0x714:取默认底色0x71C:快照0x8BC:取日期0x8C0:取时间0x8C8:读配置项0x8CC:写配置项0x8D0:取配置节名0x8D8:打开加密文件0x8D4:取操作系统类别0x8DC:是否已加密0x8E0:置数据库密码0x8E4:密码输入框0x8E8:复制密码0x914:写到内存0x904:标准输出0x90C:指针到文本0x9D4:到字节0x9D8:到短整数0x9DC:到整数0x9E0:到长整数0x9E4:到小数0x9F8:左移0x9FC:右移0xA7C:取程序名称0xA8C:取最后错误0xAA0:文本到UTF80xAA4:UTF8到文本0xAB0:反转整数字节序特殊功能支持库——spec0x1C:延迟0x24:申请内存可执行文件数据转换支持库——cnvpe0x0:转换可执行文件数据数据操作支持库——dp10x0:压缩数据0x4:解压数据0x8:取数据摘要0xC:加密数据0x10:解密数据0x14:数字签名0x18:签名验证互联网支持库——internet0x0:连接发信服务器0x4:断开发信服务器0x8:添加附件文件0xC:添加附件数据0x10:清除所有附件0x14:发送邮件0x18:置DL服务器0x1C:HTTP读文件0x20:连接FTP服务器0x24:断开FTP服务器0x28:FTP文件下载0x2C:FTP文件上传0x30:FTP删除文件0x34:FTP文件改名0x38:FTP创建目录0x3C:FTP删除目录0x40:FTP置现行目录0x44:FTP取现行目录0x48:FTP目录列表操作系统界面功能支持库——shell0x0:创建快捷方式0x4:查询快捷方式0x8:浏览文件夹0xC:删除到回收站0x10:进度复制文件0x14:进度移动文件0x18:执行0x1C:取特定目录0x20:关闭系统应用接口支持库——eAPI0x0:取键盘指示灯状态0x4:模拟按键0x8:模拟鼠标点击0xC:取硬盘信息0x10:取驱动器数量0x14:取驱动器列表0x18:弹出光驱0x1C:关闭光驱0x20:取光驱盘符0x24:光驱中是否有盘0x28:取系统进程列表0x2C:终止进程0x30:取正在使用DLL列表0x38:取系统信息0x3C:取BIOS信息0x40:取文件版本信息0x44:取CPU信息0x48:取CPU占用率0x4C:取内存容量信息0x50:取声卡名称0x54:打开监视器0x58:关闭监视器0x5C:添加右键菜单0x60:删除右键菜单0x64:设置自动运行0x68:删除临时文件0x6C:清除历史记录0x94:创建程序组0x98:删除程序组0x9C:创建程序项0xA0:删除程序项0xA4:取快捷方式目标0xA8:取网卡信息列表0xAC:取本机网卡名0xB0:取本机网卡物理地址0xB4:取远程网卡物理地址0xBC:取IP地址0xC0:撰写邮件0xC4:取网络类型列表0xC8:取网络工作组列表0xCC:取网络计算机列表0xD0:是否与互联网连接0xDC:打开特殊系统窗口0xE0:打开指定网址0xE4:隐藏桌面图标0xE8:显示桌面图标0xEC:隐藏任务栏0xF0:显示任务栏0xF4:隐藏系统时钟0xF8:显示系统时钟0xFC:隐藏开始按钮0x100:显示开始按钮0x104:设置桌面壁纸0x108:设置窗口透明度0x10C:取显示模式列表0x110:取当前显示模式0x114:设置屏幕分辨率二、组件ID0x16010030:编辑框0x16010031:图片框0x16010032:外形框0x16010033:画板0x16010034:分组框0x16010035:标签0x16010036:按钮0x1601016B:时钟0x16010006:时钟 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////最后提供的函数索引有些不一定正确,索引获取方法就是易语言写一个调用库函数,然后自己去调试器里看他穿的值。之前有想法是做一个特征然后把所有库函数的调用给识别出来,但是在库文件加载顺序不确定下又懒得去弄,就干脆不弄了。
本帖最后由 咖啡茶 于 2022-11-21 16:14 编辑
https://bbs.pediy.com/thread-274503.htm
看雪的原帖是楼主吗?转载的话还是建议表明出处 咖啡茶 发表于 2022-11-21 16:13
看雪的原帖是楼主吗?转载的话还是建议表明出处
看了,知乎的,但是好像也是看雪的,感觉方法一致总结的好就搬了 虽然看过了,还是谢谢分享! 看不懂!/笑哭 邂逅涟漪 发表于 2022-11-25 15:56
看不懂!/笑哭
慢慢来,开始也也看不懂 感谢大佬分享! 感谢大佬分享!
感谢分享,不过和看雪那个9月份帖子一模一样 果断收藏了。
页:
[1]
2