在RMXP中简单学习一下里边的Win32API函数

前段时间在捣鼓RPG Maker XP,学习一下里边的Win32API函数

这个函数可以在RMXP的引擎中调用dll中的函数,不仅可以调用系统dll(如user32.dll),也可以调用我们自己写的dll

Win32API.new("dll名", "导出函数名", '参数', '返回值')

在参数与返回值中,可以使用:

V(void),无;I(integer),整型;L(long),长整型;P(pointer),指针类型

但值得注意的是,由于RMXP是32位的,integer和long都是32位,没有区别,并且RMXP只能读取32位的dll,对于64位dll会Runtime Error

如果具有多个参数的情况下,只需要按顺序在字符串填入即可,比如:

Win32API.new("name.dll", "funcname", 'III', 'P')

‘III’表示需要调用的这个导出函数的参数是3个整型,返回值是指针类型

此外,由于其没有向我们提供float的参数,如果需要传入float,需要做一个转换

//test1.cpp
#include <windows.h>
extern "C" __declspec(dllexport) int func1(float *a) {
    float b  = *a + 1.5;
    return *(int*)&b;
}


BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
    return TRUE;
}
# Ruby
a = 2.1
b = [a].pack("e")
f = Win32API.new('test1.dll','func1','P','I')
c = f.call(b)
d = [c].pack("l").unpack("e")
p d[0]

得到输出:3.59999990463257

上面代码的原理是首先将2.1打包为一个二进制字符串数据(这里的“e“表示格式为float),然后将打包后的字符串传入函数,字符串是指针类型所以使用”P“进行传参,在dll层中将其强制解析为一个int后返回,刚才提到了RMXP没有float,所以我们需要通过int进行中转,使用这种方式不会影响原数据的二进制

返回到Ruby层后,由于返回的是一个int,所以需要先按照int类型pack成一个二进制字符串数据,随后直接将这个二进制数据解析成float,比较麻烦

一点小实际应用

下面的内容可能需要一点逆向芝士?制作RMXP游戏的动态标题效果

我们可以去查文档去找到我们所需功能的函数,可以使用http://www.yfvb.com/help/win32sdk/webhelpleft.htm

我们可以搜索到

可以看到参数需要窗口句柄和修改的标题字符串,我们再去搜索获取窗口句柄的函数

我们可以在Graphics.update里循环调用我们的修改标题的函数,具体如下:

$GetForegroundWindow = Win32API.new("user32.dll", "GetForegroundWindow", "V", "L")
$SetWindowText = Win32API.new("user32.dll", "SetWindowText", "IP" , "I")
$hwnd = $GetForegroundWindow.call
 class << Graphics
  alias ex4r26li0_update_20260319 update
  def update
    ex4r26li0_update_20260319 
    $SetWindowText.call($hwnd, Time.now.to_s)
  end
end

但是我们运行发现,程序会把标题再改回去,这里我们需要对RGSS103J.dll进行修改

RGSS103J.dll加了壳,脱一下后找到Import的函数直接搜索上面的修改标题的函数

NOP掉相关语句

这时我们发现标题已经不会被修改回去了

评论

  1. Mysterious man
    3 月前
    2026-3-19 19:55:10

    肥肠号

  2. Mysterious man2
    2 月前
    2026-4-21 20:05:37

    妃常皓

发送评论 编辑评论


				
上一篇