找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 783|回复: 8

【汇编】命名混淆:再也不怕名称冲突了以及不能“见名思义”的导出表

[复制链接]
发表于 2023-3-28 23:36:47 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 Mat 于 2023-3-29 03:29 编辑

【原创】来源:https://www.0xaa55.com/thread-27352-1-1.html
转载请注明出处。

写汇编程序的麻烦之一就是怕定义的标号名、变量名以及过程名产生名称冲突,所以通常会做一些编码规范的约定,防止以上问题的产生。不过总觉得心理负担加重了,不能愉快的写代码。或者辛辛苦苦的编写了一个dll,导出了一些函数,但别人一看导出表导出的函数名称就大概能猜测出某个函数是干什么用的,会不会觉得很不爽?如果说中了各位的痛处,那就请继续往下看。

利用MASM的宏函数进行名称混淆,混淆的规则很简单,就是进行简单的字符映射,准备2张字符序列表:
  1. C_VARNAME_DEFAULT_ALPHABET  EQU <abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPTRSTUVWXYZ0123456789_$?@>
  2. C_VARNAME_SHUFFLE_ALPHABET1 EQU <Yx4Om7LuN2XTI38S_wAtnalRhi1CcspFEoqzDGrBZ06gUHdeMKVvkTjJ5Pbf9Wy@$?>
复制代码

比如要将 Sub 进行混淆,则从第一张表中查找对应的索引,然后映射到第二张表中,就变成了:Unx,之后再附加指定的前缀,就妥了。

执行效果

执行效果


可以看到,生成的TestDll.dll中导出表中的某些全局变量及函数名称已经混淆了:
TestDll.png

以下是VarName.mac的实现:
  1. ;;=============================================================================
  2. ;;作者:Mat
  3. ;;网址:https://www.0xaa55.com/?8271
  4. ;;请保留原作者信息,否则视为侵权。
  5. ;;-----------------------------------------------------------------------------

  6. IFNDEF __VARNAME_MAC_
  7. __VARNAME_MAC_ EQU <1>

  8. IFNDEF VAR_NAME_PREFIX
  9.         VAR_NAME_PREFIX TEXTEQU <VARNAME>
  10. ELSE
  11.         IFIDN VAR_NAME_PREFIX, <>
  12.                 VAR_NAME_PREFIX TEXTEQU <VARNAME>
  13.         ENDIF
  14. ENDIF

  15. ; private
  16. C_VARNAME_DEFAULT_ALPHABET  EQU <abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPTRSTUVWXYZ0123456789_$?@>
  17. C_VARNAME_SHUFFLE_ALPHABET1 EQU <Yx4Om7LuN2XTI38S_wAtnalRhi1CcspFEoqzDGrBZ06gUHdeMKVvkTjJ5Pbf9Wy@$?>
  18. C_VARNAME_SHUFFLE_ALPHABET2 EQU <5irBYsdzMUakRcKg1IDE9C_vftmNeTbX6ZpyS3J7Hho2LGV08FAnqjux4lwTWPO?@$>

  19. ; private
  20. C_VARNAME_ALPHABET_INDEX_MIN EQU <1>
  21. C_VARNAME_ALPHABET_INDEX_MAX EQU @SizeStr(%C_VARNAME_DEFAULT_ALPHABET)


  22. ; private
  23. M_VARNAME_CharMapping MACRO chr:REQ, shuffleAlphabet
  24.         LOCAL index

  25.         index TEXTEQU @InStr(, %C_VARNAME_DEFAULT_ALPHABET, chr)

  26.         IF index
  27.                 EXITM @SubStr(shuffleAlphabet, index, 1)
  28.         ENDIF

  29.         EXITM VAR_NAME_PREFIX
  30. ENDM


  31. ; public
  32. MVN MACRO varname:REQ
  33.         LOCAL symname, chr

  34.         symname TEXTEQU @CatStr(<_>, %VAR_NAME_PREFIX, <_>)

  35.         % FOR num, <1,2>
  36.                 % FORC chr, varname
  37.                         symname TEXTEQU @CatStr(%symname, M_VARNAME_CharMapping(chr, %C_VARNAME_SHUFFLE_ALPHABET&num))
  38.                 ENDM
  39.         ENDM

  40.         symname TEXTEQU @CatStr(%symname, <_>, %(@SizeStr(%symname) - @SizeStr(%VAR_NAME_PREFIX) - 2), <_>)

  41.         EXITM <symname>
  42. ENDM


  43. ;% ECHO Generate VarName: MVN(<gHello>)

  44. ENDIF
复制代码


只需要引入 VarName.mac,调用宏函数 MVN 即可。
但是有一个问题,就是如果用于 dll 的话,需要生成相应在的 .def 文件,这个我用 VBScript 实现了。Def.vbs 代码如下:
  1. '=============================================================================
  2. '作者:Mat
  3. '网址:https://www.0xaa55.com/?8271
  4. '请保留原作者信息,否则视为侵权。
  5. '-----------------------------------------------------------------------------
  6. Option Explicit


  7. Const DEFAULT_ALPHABET  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPTRSTUVWXYZ0123456789_$?@"
  8. Const SHUFFLE_ALPHABET1 = "Yx4Om7LuN2XTI38S_wAtnalRhi1CcspFEoqzDGrBZ06gUHdeMKVvkTjJ5Pbf9Wy@$?"
  9. Const SHUFFLE_ALPHABET2 = "5irBYsdzMUakRcKg1IDE9C_vftmNeTbX6ZpyS3J7Hho2LGV08FAnqjux4lwTWPO?@$"

  10. Const VAR_NAME_PREFIX                       = "VARNAME"
  11. Const ALPHABET_INDEX_MIN                    = 1
  12. Dim  ALPHABET_INDEX_MAX: ALPHABET_INDEX_MAX = Len(DEFAULT_ALPHABET)


  13. Function CharMapping(char, shuffleAlphabet)
  14.         Dim pos: pos = InStr(1, DEFAULT_ALPHABET, char, vbBinaryCompare)

  15.         If pos = 0 Then
  16.                 CharMapping = VAR_NAME_PREFIX
  17.         Else
  18.                 CharMapping = Mid(shuffleAlphabet, pos, 1)
  19.         End If
  20. End Function


  21. Function StrMapping(vname, shuffleAlphabet)
  22.         Dim symname: symname = ""

  23.         Dim i
  24.         For i = 1 To Len(vname) Step 1
  25.                 symname = symname & CharMapping(Mid(vname, i, 1), shuffleAlphabet)
  26.         Next

  27.         StrMapping = symname
  28. End Function


  29. Function VarName(vname, prefix)
  30.         Dim strPrefix
  31.         If IsEmpty(prefix) Or IsNull(prefix) Or prefix="" Then
  32.                 strPrefix = VAR_NAME_PREFIX
  33.         Else
  34.                 strPrefix = prefix
  35.         End If

  36.         Dim symname: symname = "_" & strPrefix & "_"

  37.         symname = symname & StrMapping(vname, SHUFFLE_ALPHABET1)
  38.         symname = symname & StrMapping(vname, SHUFFLE_ALPHABET2)
  39.         symname = symname & "_" & (Len(symname) - Len(strPrefix) - 2) & "_"

  40.         VarName = symname
  41. End Function

  42. Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")

  43. If WScript.Arguments.Count < 1 Then
  44.         WScript.Echo "缺少参数:", Chr(13), Chr(10), Chr(9), "Usage: cscript Def.vbs <Dll Name>.def [VarName Prefix String]"
  45.         WScript.Quit
  46. End If

  47. Dim strPrefix: strPrefix = ""
  48. If WScript.Arguments.Count > 1 Then
  49.         strPrefix = Trim(WScript.Arguments(1))
  50.         If Len(strPrefix) < 1 Then
  51.                 strPrefix = VAR_NAME_PREFIX
  52.         End If
  53. End If

  54. Dim defFileName: defFileName = Trim(WScript.Arguments(0))
  55. If fso.FileExists(defFileName) Then
  56.         fso.DeleteFile defFileName, True
  57. End If

  58. Const ForReading = 1, ForWriting = 2

  59. Dim defTplFile: Set defTplFile = fso.OpenTextFile("def.tpl", ForReading)
  60. Dim defFile: Set defFile = fso.OpenTextFile(defFileName, ForWriting, True)

  61. defFile.WriteLine "LIBRARY " & fso.GetBaseName(defFileName) & ".dll"
  62. defFile.WriteLine "EXPORTS"

  63. Do While Not defTplFile.AtEndOfStream
  64.         Dim line: line = Trim(defTplFile.ReadLine)
  65.         If line <> "" Then
  66.                 If Left(line, 1) = "!" Then
  67.                         line = Mid(line, 2)
  68.                 Else
  69.                         Dim i
  70.                         Dim strName: strName = ""
  71.                         Dim strChar
  72.                         For i = 1 To Len(line)
  73.                                 strChar = Mid(line, i, 1)
  74.                                 If strChar = " " Or strChar = "\t" Or strChar = "\r" Or strChar = "\n" Then Exit For
  75.                                
  76.                                 strName = strName & strChar
  77.                         Next

  78.                         line = VarName(strName, strPrefix) & Mid(line, i)
  79.                 End If

  80.                 defFile.WriteLine Chr(9) & line
  81.         End If
  82. Loop

  83. defTplFile.Close
  84. defFile.Close

  85. Set defTplFile = Nothing
  86. Set defFile = Nothing
  87. Set fso = Nothing
复制代码


事实上 Def.vbs 也实现了 VarName.mac 的混淆算法,在编译 dll 前,执行 Def.vbs 生成相应的模块定义文件 .def。Def.tpl 是用于生成 .def 的模板,用于定义导出的全局变量及函数,模板中以 ! 开头的名称表示不进行名称混淆,接下来进行编译:
  1. cscript /nologo Def.vbs $(DLL).def $(VAR_NAME_PREFIX)
复制代码

并且可以指定名称前缀,当然在编译的时候也同样需要指定,帖上 Makefile:
  1. NAME=Test
  2. OBJS=$(NAME).obj
  3. RES=$(NAME).res
  4. DLL=TestDll

  5. VAR_NAME_PREFIX=0x3f3f3f3f

  6. ML_FLAG=/nologo /c /coff /DVAR_NAME_PREFIX=$(VAR_NAME_PREFIX)
  7. LINK_FLAG=/nologo /subsystem:windows

  8. $(NAME).exe: $(OBJS) $(RES) $(DLL).obj $(DLL).dll
  9.         link32 $(LINK_FLAG) /out:$(NAME).exe $(OBJS) $(RES)
  10.         start $(NAME).exe
  11. VarNameDll.obj:
  12.         ml $(ML_FLAG) $(DLL).asm
  13. .asm.dll:
  14.         cscript /nologo Def.vbs $(DLL).def $(VAR_NAME_PREFIX)
  15.         link32 $(LINK_FLAG) /dll /def:$(DLL).def $(DLL).obj
  16. .asm.obj:
  17.         ml $(ML_FLAG) $<
  18. .rc.res:
  19.         rc $<
  20. clean:
  21.         del /q *.obj > nul 2>&1
  22.         del /q *.pdb > nul 2>&1
  23.         del /q *.ilk > nul 2>&1
  24.         del /q *.lst > nul 2>&1
  25.         del /q *.map > nul 2>&1
  26.         del /q *.res > nul 2>&1
  27.         del /q *.exp > nul 2>&1
  28.         del /q *.lib > nul 2>&1
  29.         del /q *.dll > nul 2>&1
  30.         del /q *.exe > nul 2>&1
复制代码


用 nmake 进行编译:
  1. nmake clean && nmake
复制代码


接下来是写了下dll,并且在一个主模块中调用这个dll,代码很简单,就直接帖上来了。
TestDll.asm:
  1. .386
  2. .model flat, stdcall
  3. option casemap:none

  4. ;=============================================================================
  5. ;作者:Mat
  6. ;网址:https://www.0xaa55.com/?8271
  7. ;请保留原作者信息,否则视为侵权。
  8. ;-----------------------------------------------------------------------------

  9. include windows.inc
  10. include user32.inc

  11. includelib user32.lib

  12. include TestDll.inc

  13. public gTitle
  14. public MVN(<gHello>)
  15. public MVN(<gGoodBye>)

  16. .data
  17. gTitle BYTE 'VarName Test', 0
  18. MVN(<gHello>) BYTE 'Hello, World!', 0
  19. MVN(<gGoodBye>) BYTE 'Good Bye My Love!', 0

  20. .code
  21. DllMain PROC hinstDLL:HINSTANCE, fdwReason:DWORD, lpvReserved:LPVOID
  22.         mov eax, TRUE

  23.         ret
  24. DllMain ENDP

  25. MVN(<SayHello>) PROC STDCALL _lpTitle:PBYTE
  26.         INVOKE MessageBox, NULL, ADDR MVN(<gHello>), _lpTitle, MB_OK

  27.         ret
  28. MVN(<SayHello>) ENDP

  29. _SayGoodBye PROC STDCALL _lpMessage:PBYTE
  30.         INVOKE MessageBox, NULL, _lpMessage, ADDR gTitle, MB_OK

  31.         ret
  32. _SayGoodBye ENDP
  33. end DllMain
复制代码


Test.asm:
  1. .386
  2. .model flat, stdcall
  3. option casemap:none

  4. ;=============================================================================
  5. ;作者:Mat
  6. ;网址:https://www.0xaa55.com/?8271
  7. ;请保留原作者信息,否则视为侵权。
  8. ;-----------------------------------------------------------------------------

  9. include windows.inc
  10. include kernel32.inc
  11. include user32.inc
  12. include msvcrt.inc

  13. includelib kernel32.lib
  14. includelib user32.lib
  15. includelib msvcrt.lib

  16. include Test.inc

  17. includelib TestDll.lib

  18. .data
  19. hDllInstance HINSTANCE 0

  20. .code
  21. start:
  22. INVOKE GetModuleHandle, M_TEXT(<TestDll>)
  23. mov hDllInstance, eax

  24. ; SayHello
  25. INVOKE GetProcAddress, hDllInstance, M_TEXT(<gTitle>)
  26. INVOKE MVN(<SayHello>), eax

  27. ; _SayGoodBye
  28. INVOKE GetProcAddress, hDllInstance, M_TEXT(%MVN(<gGoodBye>))
  29. INVOKE _SayGoodBye, eax

  30. INVOKE ExitProcess, NULL
  31. end start
复制代码


VarName.zip (4.8 KB, 下载次数: 1, 售价: 2 个宅币)
回复

使用道具 举报

发表于 2023-3-29 08:54:10 | 显示全部楼层
不开发.dll的就没那么多担忧了,直接开发静态库
回复 赞! 靠!

使用道具 举报

发表于 2023-3-29 09:50:49 | 显示全部楼层
现在的 C/C++ 编译器都在链接时间进行代码生成,写静态库就行了。静态库里面的 obj 包含链接时间代码生成所需的字节码,在进行代码生成的时候可以进行一次总的优化,包括但不限于跨编译单元的函数内联、自动剔除未用函数和变量、把特定变量固定为常量后生成某个函数的常量特化版等,编译出来的程序是不包含任何符号也不需要考虑任何混淆的,因为早就被优化得面目全非了。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2023-3-29 12:12:28 | 显示全部楼层
照这么说dll退出历史舞台好了更别说用masm写dll了。
而且这种方式更大的好处就算不写dll,也没有给变量取名的困扰,快哉!
回复 赞! 靠!

使用道具 举报

发表于 2023-3-29 18:46:43 | 显示全部楼层
Mat 发表于 2023-3-29 12:12
照这么说dll退出历史舞台好了更别说用masm写dll了。
而且这种方式更大的好处就算不写dll,也没有 ...


dll是可以不用的,dll主要是为了节省内存和硬盘,因为早期系统资源有限
苹果最早就不支持开发动态库这种东西,后来才支持,因为仅使用静态库其二进制实在太大了。
Win上个人开发的小软件也大不到哪去,静态库爽歪歪。而且就像a5说的,一起链接的,可以达到最大化二进制优化,增加破解难度。
回复 赞! 靠!

使用道具 举报

发表于 2023-3-30 15:32:19 | 显示全部楼层
不过总觉得心理负担加重了,不能愉快的写代码。或者辛辛苦苦的编写了一个dll,导出了一些函数,但别人一看导出表导出的函数名称就大概能猜测出某个函数是干什么用的,会不会觉得很不爽?
你的目的是为了干扰破解者吗?如果是的话,直接上VMP、TMD之类的工具。或者上网络验证,重要的程序数据只有在验证之后才下发。

如果是为了防止DLL被盗用,可以给程序加自定义的数字签名,只有数字签名验证通过,才进行初始化。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2023-3-31 03:35:45 | 显示全部楼层
本帖最后由 Mat 于 2023-3-31 03:42 编辑
美俪女神 发表于 2023-3-30 15:32
你的目的是为了干扰破解者吗?如果是的话,直接上VMP、TMD之类的工具。或者上网络验证,重要的程序数据只有 ...


这个越说越远了。

1、这里只说了用在masm开发上;
2、声明变量和过程方便,不用考虑名称冲突;
3、对dll的导出表导出的函数名能起到一定的名称混淆作用。
4、并没有说要干扰破解者,但至少能在一定程度上增加点代价吧。

总之:只是常规开发中的一些小想法,请高手自动略过。
回复 赞! 靠!

使用道具 举报

发表于 2023-4-13 08:48:45 | 显示全部楼层
Mat 发表于 2023-3-31 03:35
这个越说越远了。

1、这里只说了用在masm开发上;

dll导出表根本没有必要混淆,直接按编号匿名导出就行了。
回复 赞! 靠!

使用道具 举报

发表于 2023-5-13 18:30:54 | 显示全部楼层
YY菌 发表于 2023-4-13 08:48
dll导出表根本没有必要混淆,直接按编号匿名导出就行了。

是的,在十年前我的确是这样做的。

一种“我才不管三个月后的自己如何解开”的爽快感wwww
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-10-8 17:03 , Processed in 0.049353 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表