OpenAi的Chatgpt与许多类似的大型语言模型一样,已被用来执行许多与编程相关的任务。编写混淆映射似乎非常适合其能力,因为它涉及阅读和总结文本(代码)。我测试了它的功能。
背景
如果您已经了解了什么混淆映射,请随时跳过此部分。
Minecraft:Java Edition 是用Java编写的游戏( Quelle Surprise )。 Java源代码已编译到JVM字节码进行分发,有点像C和机器代码之间的关系。
要修改游戏,我们希望访问Java源。但是,有两件事:
首先,我们必须 empodile jar,将字节码转换回Java。这是一项非常困难的工作:在tools中进行了很多工作来实现这一目标。
但是,即使那样,我们也没有可读的代码:Minecraft的开发人员Mojang将其代码放在ProGuard上,该代码通过将所有方法和类别命名为a
,b
,b
,c
,c
,c
,c
,缩小字节码来缩小字节码。 ,az
,等等。因此,我们需要这些混淆名称中的映射到可读名称!
有一段时间,可用的主要映射由MCP项目进行,并获得了限制性许可。这些首先是由MCP本身和后来的Minecraft Forge使用的,Minecraft Forge(Modloader和API。
当另一个Modloader/API项目Fabric于2018年进入现场时,它必须自己制作自己的映射,称为Yarn。它可以免费提供纱线(CC-0),并实现了“洁净室政策” - 任何面料社区空间中都不会提及MCP名称,以防严格许可的MCP映射“污染”纱线贡献者。<<<<<<<<<<<<<<<<<<<<< /p>
因此,映射被破裂了。因为每个班级都有两个名称。 “ Lo,” said Mojang,“我们将向他们授予他们的正式映射设置,并从Proguard本身出口”。
Forge迅速切换到官方映射。面料决定非公共域映射集不会做。此外,这些名字都有些奇怪,而且与他们无论如何都不同,因此他们更喜欢维护和使用自己的映射,非常感谢。
这些天,有四个主要映射集:
- Official Mappings(又名Mojmap)完全像Mojang看到但没有参数名称。
- Parchment是一个为参数名称创建映射的项目,还包括Javadoc,将分层放在官方映射的顶部。
- Yarn,仍然带着洁净室来防止不再存在的映射套件。
- Quilt Mappings。被子是许多以前的开发商制造的织物。被子映射就像纱一样,但没有洁净室,因此可能会从官方映射中汲取灵感。它的主要目的是像纱一样,但要像Mojmappier,或者像Mojmap一样,但是Yarnier-取决于您的要求。
首先测试
首先,我设置了一个被子映射工作区。为什么要被子映射而不是纱?两个原因:
- QM缺少更多内容的映射,因此更容易找到用于测试的混淆名称。
- QM工作空间允许使用QuiltFlower分解器,它比许多其他分解器都能产生更好的输出。
我花了几次尝试找到一个很好的提示。我解决了这个问题:
我在
ClassName
中有这种Java方法,但我不知道该怎么称呼:code snippet
请为此方法及其每个参数建议一个名称。
本地图#版权
我首先在NativeImage
中尝试了此方法:
public void m_vmneozhc(NativeImage arg, int i, int j, int k, int l, int m, int n, boolean bl, boolean bl2) {
for(int o = 0; o < n; ++o) {
for(int p = 0; p < m; ++p) {
int q = bl ? m - 1 - p : p;
int r = bl2 ? n - 1 - o : o;
int s = this.getPixelColor(i + p, j + o);
arg.setPixelColor(k + q, l + r, s);
}
}
}
它建议我称之为copyImage(NativeImage sourceImage, int sourceX, int sourceY, int targetX, int targetY, int width, int height, boolean flipHorizontally, boolean flipVertically)
。
这很好! Mojang称之为copyRect
方法,与Chatgpt的命名非常相似。它也明智地名称参数。
Localplayer#sendissprintingifneed
接下来,我在QM调用ClientPlayerEntity
的类中尝试了此方法(但是Mojang调用LocalPlayer
):
private void m_nfwipcth() {
boolean bl = this.isSprinting();
if (bl != this.lastSprinting) {
ClientCommandC2SPacket.Mode lv = bl ? ClientCommandC2SPacket.Mode.START_SPRINTING : ClientCommandC2SPacket.Mode.STOP_SPRINTING;
this.networkHandler.sendPacket(new ClientCommandC2SPacket(this, lv));
this.lastSprinting = bl;
}
}
它建议updateSprintingStatus()
。
这是不是错误的,但它作为一个名称有点通用 - 它并没有捕获它涉及通过网络告诉服务器有关播放器的冲刺状态的信息。
MultiplayerGamemode#permansuseitemon
让我们尝试更长的方法。这次我不会向您展示整个方法(毕竟Minecraft是封闭消息),但是我会在类QM Call ClientPlayerInteractionManager
中向您展示此方法的摘要,而Mojang call kude13:
private ActionResult m_wiqrsdhj(ClientPlayerEntity arg, Hand arg2, BlockHitResult arg3) {
BlockPos lv = arg3.getBlockPos();
ItemStack lv2 = arg.getStackInHand(arg2);
if (this.gameMode == GameMode.SPECTATOR) {
return ActionResult.SUCCESS;
} else {
// ...
这没关系。该方法在右键单击块上时运行 - 但仅在持有项目时才运行。 Chatgpt的名字并没有真正捕捉到这一点。尽管如此,它不如Mojang的performUseItemOn
丑陋。
可以做更多吗?
所以chatgpt可以命名方法,不是完美,而是好的。但是它可以映射整个类吗?
我在此提示中尝试了一下:
我有这个Java类,但所有名称都乱七八糟:
code snippet
对于上下文,
。 对于每个乱码的名称,建议一个专有名称。
BlockStatePredictionHandler
我找到了一个没有用QM映射的课程-Mojang称其为BlockStatePredictionHandler
-并将其粘在提示中。我也添加了一些上下文:
对于上下文,
ClientWorld
类具有此类的私人最终字段。该类的方法从ClientWorld
和ClientPlayerInteractionManager
的类中调用。
占位符 | mojmap | chatgpt |
---|---|---|
C_czisrdmd |
BlockStatePredictionHandler |
BlockStateTracker |
f_irkdwisi |
serverVerifiedStates |
blockStateMap |
f_hcvpxtyt |
currentSequenceNr |
tickCounter |
f_bmpbngyn |
isPredicting |
isTracking |
m_plwiurco |
retainKnownServerState |
addBlockState |
m_mmtdqsga |
updateKnownServerState |
updateBlockState |
m_vfahppjl |
endPredictionsUpTo |
rollbackBlockStates |
m_rhbdpkkw |
startPredicting |
startTracking |
close |
n/a | stopTracking |
m_gqtwgmpw |
currentSequence |
getTickCounter |
m_nssimvch |
isPredicting |
isTracking |
C_ivvmpfib |
ServerVerifiedState |
TrackedBlockState |
f_bfinrexc |
playerPos |
playerPosition |
f_ovpelcnt |
sequence |
trackedTick |
state |
blockState |
blockState |
m_twfpffxt |
setSequence |
updateTrackedTick |
m_fxchmlnj |
setBlockState |
updateBlockState |
虽然Chatgpt的名字连贯,并且肯定是一致的(请参阅字段与其getters/setter之间的一致性),但它存在一些缺陷。参见,例如,它如何尝试重命名close
,这是一种从java的AutoCloseable
继承的非弹性名称。
我不知道这堂课的目的,所以我问了chatgpt-也许这也可以让我们了解为什么它以其方式命名符号?
至少最后一部分是完全不正确的 - 在创意模式下,玩家进行的块变化肯定是不是不是在玩家离开游戏时回滚。对其余的解释进行了怀疑,因此我搜索了一些不和谐服务器,以查看其他人是否有解释。
这是SizableShrimp的(修剪)解释。
基本上,客户在其
BlockStatePredictionHandler
中跟踪序列计数器。当客户端想要执行MultiPlayerGameMode
中的任何块修改操作时,它将通过增加计数器来为新的序列编号。
现在,在预测模式下,对ClientLevel#setBlock
的任何呼叫实际上都不会在世界内设置!它们将存储在预测处理程序中。
现在,在客户端完成其客户端块修改操作后,该序列编号与客户端要求执行的操作一起发送到服务器。然后,服务器将执行客户端请求的块修改操作(如果可能的话)。
一旦服务器“完成”,它将将数据包发送回客户端,该客户端启动操作以处理所有块序列到该序列ID。
他们使用此预测性动作系统,因此客户认为应该发生的事情与服务器的实际执行不同时,客户端没有视觉故障。
客户现在将在预测操作期间延迟设置块,等待实际发生的事情的服务器响应,然后在客户端上更新。
(在Forge Discord上的this message中提供了完整的解释)
有趣的 - 因此,chatgpt正确地告诉我们,类跟踪块会更改并可以向后滚动,但它误解了序列编号是tick计数器,并且不明白该类用于持续下去,预测直到服务器验证。
实际上,它不了解 。这是要求Chatgpt向您解释某些东西的缺陷之一 - 它没有一致的世界内部模型。与其他大型语言模型一样,Chatgpt只能阅读一些文字并写出更多听起来应该是后来的文本 - 结果,很容易给出有关事物的完全不正确的答案,同时听起来非常自信和权威。<<<<<<<<<<<<<< /p>
矩阵
让我们再试一次。这有一些方法可以弄乱矩阵。它在QM中未映射; Mojang称其为MatrixUtil
。与我们的其他测试相比,这是很长的(〜200行)。
我给了Chatgpt,上下文:
对于上下文,
m_xockxffa
从ItemRenderer
类中称为m_jeovkadj
和m_jeovkadj
和m_ibrymiig
从类AffineTransformation
中调用。
占位符 | mojmap | chatgpt |
---|---|---|
C_bmzqkdhp |
MatrixUtil |
MatrixMathHelper |
f_arxnkhow |
G |
RADIUS_FACTOR |
f_ddnzxrmh |
CS |
COSINE_OF_45_DEGREES |
f_kqccjreh |
SS |
SINE_OF_45_DEGREES |
m_xockxffa |
mulComponentWise |
scaleMatrix |
m_kcqrzkbi |
approxGivensQuat |
computeUnitVectors |
m_kniviwwf |
qrGivensQuat |
computeUnitVectorsFromYawPitch |
m_skxdryqk |
stepJacobi |
computeQuaternionFromMatrix |
m_kkfnnzhk |
n/a | computeQuaternionFromYawPitch |
m_kjbxjxks |
n/a | computeUnitVectorsFromQuaternion |
m_pjmgwfwq |
n/a | computeMatrixFromQuaternion |
m_geumxflx |
n/a | computeMatrixFromYawPitch |
m_ibrymiig |
svdDecompose |
n/a |
m_jeovkadj |
toAffine |
n/a |
命名为常数的人一定是数学家。
chatgpt有一个良好的开端:MatrixMathHelper
是一个可靠的名称; SINE
和COSINE
_OF_45_DEGREES
具有描述性(令人印象深刻的是,它是按弧度计算的)。不幸的是,它从那里下坡。
其余的名称看起来描述性 - 在许多情况下,他们乍看之下比Mojang的名字更好。但是,再次,这是一种善于听起来很自信的情况,同时完全不正确。
所谓的scaleMatrix
方法,采用4x4矩阵和浮点,并返回一个与每个元素乘以浮子的矩阵,以一种将矩阵量表乘法与缩放的线性变换混淆的方式。
computeQuaternionFromMatrix
是一个技术上正确的名称 - 该方法采用3x3矩阵并返回四个矩阵。但是它无法传达该方法的实际作用。 stepJacobi
至少要点您in the right direction。
不过,还有一个更加令人讨厌的问题:chatgpt开始幻觉方法。
在桌子中,您会看到一些没有chatgpt名称的方法(因为它分散了注意力并且没有命名),还有一些没有mojang名称的方法(因为它们不存在 - chatgpt使他们成立了)。
哦,亲爱的。
结论
chatgpt是一个有趣的工具。毫无疑问,它非常擅长文本预测和发电。这有时会概括地解释,总结并似乎理解文本背后的含义。这不是真的 - 它无法理解含义。
对于DeobFuscation名称映射,大型语言模型(例如Chatgpt)可能可用作assistive tools。他们不能依靠自动化命名过程。
在Minecraft的特定情况下,存在Mojmap的存在,维持替代映射的价值有限。增强Mojmap有更多的价值,例如羊皮纸。因此,查看如何使参数名称和写作Javadoc的过程更加高效将很有用。
参数命名的错误空间比类/成员命名更少。大型语言模型可用于帮助自动化此过程 - 但是,专门的非ML工具可能会或更有用。
请继续关注 - 我将测试Chatgpt在另一篇文章中编写分解方法的Javadoc的能力。我不怀疑它会做得很好。
谢谢:
- Shedaniel的Linkie,一种非常有用的工具,用于在映射之间翻译。
- QM和纱contributors
- OpenAI.
- Quiltflower contributors。