0%

修改daemon.json配置文件

往docker的daemon.json配置文件中添加registry-mirrors条目。

对于Linux环境路径一般为:

1
/etc/docker/daemon.json

对于Windows环境路径一般为:

1
%USERPROFILE%/.docker/daemon.json

给daemon.json添加以下内容:

1
2
3
4
5
"registry-mirrors": [
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]

notes:以上三个镜像源,目前都已经失效了,可以到阿里云的镜像工具中,生成个镜像加速器地址。

重启docker服务使配置生效

阅读全文 »

启用categories(分类)页面

  1. 创建categories page
1
hexo new page "categories"

​ 这会在./source创建一个categories的页目录

  1. 编辑./source/categories/index.md
1
2
3
4
5
6
---
title: categories
date: 2022-07-12 10:08:04
type: "categories"
comments: true
---

​ 其中的关键是type属性

  1. 修改主题配置(这里以next主题为例)

​ 编辑./themes/next/_config.yml,把menu下的categories注释取消掉

1
2
3
4
5
6
7
8
9
menu:
home: / || fa fa-home
#about: /about/ || fa fa-user
#tags: /tags/ || fa fa-tags
categories: /categories/ || fa fa-th
archives: /archives/ || fa fa-archive
#schedule: /schedule/ || fa fa-calendar
#sitemap: /sitemap.xml || fa fa-sitemap
#commonweal: /404/ || fa fa-heartbeat
阅读全文 »

以检测lua_pcall调用为例子,执行某个自定义的Lua脚本函数调用会进入一个死循环,现在要做的是让它在超过一定时间未执行完毕,就让出,跳出死循环。

基本原理

  1. 在调用lua_pcall之前记录调用前的时间戳

  2. 启动新线程,检测超时

  3. 调用lua_pcall

  4. 如果在新线程中检测到超时,那么启用钩子

1
2
// 这里最好用LUA_MASKLINE,即每执行一个新语句前断下来
lua_sethook(L, hook_func, LUA_MASKLINE, 0);
  1. 进入钩子函数后,先把钩子去掉
1
lua_sethook(L, nullptr, 0, 0);
  1. 然后调用luaL_error让出

封装C++钩子处理函数以及相关宏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 钩子处理函数
void wxbox::plugin::internal::PluginVirtualMachineHookHandler(lua_State* L, lua_Debug* debugInfo)
{
WXBOX_UNREF(debugInfo);

lua_sethook(L, NULL, 0, 0);
luaL_error(L, "plugin virtual machine long task timeout");
}

// 获取当前以毫秒为单位的时间戳
std::time_t GetCurrentTimestamp()
{
auto t = std::chrono::system_clock::now().time_since_epoch();
return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
}

//
// 宏
//

#define BEGIN_PLUGIN_VIRTUAL_MACHINE_LONG_TASK_WITH_TIMEOUT(vm) \
{ \
auto __task_begin_timestamp = GetCurrentTimestamp(); \
std::promise<void> __task_complete_signal; \
\
auto __task_async_future = std::async( \
std::launch::async, [__task_begin_timestamp, vm](std::future<void> taskFuture) { \
for (;;) { \
if (taskFuture.wait_for(std::chrono::milliseconds(10)) != std::future_status::timeout) { \
/* task complete */ \
break; \
} \
\
if (GetCurrentTimestamp() - __task_begin_timestamp >= vm->longTaskTimeout) { \
/* timeout */ \
lua_sethook(vm->state, PluginVirtualMachineHookHandler, LUA_MASKLINE, 0); \
break; \
} \
} \
}, \
std::move(__task_complete_signal.get_future()));

#define END_PLUGIN_VIRTUAL_MACHINE_LONG_TASK_WITH_TIMEOUT(vm) \
CANCEL_PLUGIN_VIRTUAL_MACHINE_LONG_TASK(vm); \
}

#define CANCEL_PLUGIN_VIRTUAL_MACHINE_LONG_TASK(vm) \
{ \
__task_complete_signal.set_value(); \
__task_async_future.wait(); \
lua_sethook(vm->state, NULL, 0, 0); \
}

使用方法

阅读全文 »

自定义wegame入口

工具

调试工具: x64dbg

二进制编辑器:010 Editor

PE工具: Stud_PE

dump工具: Scylla

基本思路

修改wegame的入口点,优先执行自定义的dll导出的函数,验证通过后再跳转回原始的wegame入口点执行下去,如果验证不通过将直接exit掉

操作流程

  1. 使用Stud_PE添加"YourFatherServer.dll"导出的"_entry@0"函数

  2. 在wegame.exe的.text段中找一段足够长的空白区域来存放添加的新代码,这段代码这里可以把它叫做shellcode

    ​ 用010 Editor配合正则来从wegame.exe中搜索,找到空白区域在.text的相对偏移记录下来。要加入的shellcode大概有170多字节,所以最好找一块180字节的空白区域。空白指令可以用int3、nop或者0x00来定位,正则如下:

    1
    (?<!\xcc)(\xcc){180}或(?<!\x00)(\x00){180}

    ​ 要注意的是空白区域得是.text段的,找到后把这块区域的起始文件偏移减去.text段的起始文件偏移,得到这块空白区域在.text段的相对偏移。进入调试模式后,把.text段的起始虚拟地址加上这个偏移量就可以得到空白区域在内存的虚拟地址了。如果没有找到这么大的空白区域可以用Stud_PE加入一个新的.text段,把shellcode放到这里

  3. 使用x32dbg挂起wegame.exe,运行到wegame.exe的OEP处,并把OEP记录下来

  4. 查看进程的内存布局获取进程的基址,把这个地址跟第二步记录的空白区域偏移地址相加,得到空白区域的虚拟地址,把这个地址叫做fill_point

  5. 跳转到fill_point,把shellcode复制到这里,这段shellcode分成两部分,一部分是数据另一部分是代码,数据放着两个字符串,一个是"YourFatherServer.dll",另一个是"_entry@0",这在shellcode获取entry地址的时候要用。把代码部分的开始部分的地址记录下来,叫做shellcode_entry

  6. 回到OEP,往下找到第一个call指令,并把它的跳转地址记录下来,叫做origin_routine。然后把跳转地址修改为shellcode_entry

  7. 再跳到shellcode_enetry,并把最后一条jmp指令的跳转地址修改为origin_routine

  8. 打开Scylla,填入之前记录的OEP,点击重新查找导入表,再点击获取导入表,最后点击转存出去

阅读全文 »