冰楓論壇

標題: x64 Dll + Asm + NT Api hook VC++ sample code [打印本頁]

作者: kkmomo    時間: 2022-2-27 04:12
標題: x64 Dll + Asm + NT Api hook VC++ sample code
本帖最後由 kkmomo 於 2022-2-27 04:16 編輯

Tested for TwMS 241.1 MapleStory.exe
全部5個檔案,下面直接貼 source ,不另附檔案下載

範例中數據皆取自本站的 新 楓之谷(MapleStory) 遊戲代碼分享區

檔案列表:
Assembly.asm
dllmain.cpp
X64AsmSample.sln
X64AsmSample.vcxproj
X64AsmSample.vcxproj.filters

此範例實作:
1. CRC bypass (沒用到 asm)
    注入 dll 後直接寫入

2. Boss 無敵 Asm + 開關
    預設為關
    call SetBossInvincibleEnable(BOOLEAN Enable) 設定開/關

3. 全職業攻擊技能無延遲 Asm + 開關
    預設為關,速度5
    call SetAttackNoDelay(BOOLEAN Enable)  設定開/關
    call SetAttackNoDelayValue(DWORD Value) 設定速度

4. Nt Api Hook Asm + hook function
    以 Hook NtQuerySystemInformation 為例
    當 SystemInformationClass == SystemProcessInformation 時
    印出 pid 跟 process image name

Assembly.asm
  1. ; ASSEMBLE CODE

  2. ; Exportation
  3. PUBLIC BossInvincible
  4. PUBLIC AttackNoDelay
  5. PUBLIC NtQuerySystemInformation_Orig


  6. ; Importation
  7. EXTERN g_controlData_Enable_BossInvincible:QWORD
  8. EXTERN g_controlData_Enable_NoDelay:QWORD
  9. EXTERN g_controlData_NoDelayValue:QWORD

  10. ; Declaration
  11. .DATA
  12. g_noDelayCount DB 00H


  13. ; Implementation
  14. .CODE

  15. BossInvincible PROC
  16.   mov rcx, [g_controlData_Enable_BossInvincible]
  17.   cmp byte ptr [rcx], 01H
  18.   je BossInvincible_Enable
  19.   mov rcx, 140531EC0H
  20.   push rcx
  21.   mov ecx, [rcx+00000850H]
  22.   ret
  23. BossInvincible_Enable:
  24.   mov eax,01H
  25.   ret
  26. BossInvincible ENDP

  27. AttackNoDelay PROC
  28.   mov rcx, [g_controlData_Enable_NoDelay]
  29.   cmp byte ptr [rcx], 01H
  30.   jne AttackNoDelay_Orig
  31.   mov rcx, [g_controlData_NoDelayValue]
  32.   mov al, byte ptr [rcx]
  33.   cmp byte ptr [g_noDelayCount], al
  34.   jae AttackNoDelay_Orig
  35.   inc byte ptr [g_noDelayCount]
  36.   jmp SkipSetAction
  37. AttackNoDelay_Orig:
  38.   mov byte ptr [g_noDelayCount], 0
  39.   mov [rsi+00000864H],r13d
  40. SkipSetAction:
  41.   mov rax,[r14]
  42.   mov [rsp+20H],ebx
  43.   mov rcx,1434F9CD7H
  44.   jmp rcx
  45. AttackNoDelay ENDP

  46. NtQuerySystemInformation_Orig PROC
  47.   mov r10,rcx
  48.   mov eax,00000036H
  49.   syscall
  50.   ret
  51. NtQuerySystemInformation_Orig ENDP

  52. END
複製代碼
dllmain.cpp
  1. #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
  2. // Windows Header Files
  3. #define WIN32_NO_STATUS
  4. #include <windows.h>
  5. #undef WIN32_NO_STATUS
  6. #include <ntstatus.h>
  7. #include <shlwapi.h>
  8. #include <winternl.h>
  9. #include <tchar.h>
  10. #include <stdio.h>

  11. #pragma comment(lib, "Shlwapi.lib")

  12. #define _DEBUG_TAG_ L"sample"
  13. #define _FMT_PREFIX_ _DEBUG_TAG_ L": %s L%d "
  14. #define _FMT_NEWLINE_ L"\r\n"
  15. #define my_log(fmt, ...) mylog(_FMT_PREFIX_ _T(fmt) _FMT_NEWLINE_, __FUNCTIONW__, __LINE__, __VA_ARGS__)
  16. #define TARGET_PROCESS_NAME L"MapleStory.exe"

  17. #ifndef RtlOffsetToPointer
  18. #define RtlOffsetToPointer(B,O)  ((PCHAR)( ((PCHAR)(B)) + ((ULONG_PTR)(O))  ))
  19. #endif

  20. typedef struct _SYSTEM_PROCESS_INFO
  21. {
  22.     ULONG                   NextEntryOffset;
  23.     ULONG                   NumberOfThreads;
  24.     LARGE_INTEGER           Reserved[3];
  25.     LARGE_INTEGER           CreateTime;
  26.     LARGE_INTEGER           UserTime;
  27.     LARGE_INTEGER           KernelTime;
  28.     UNICODE_STRING          ImageName;
  29.     ULONG                   BasePriority;
  30.     HANDLE                  ProcessId;
  31.     HANDLE                  InheritedFromProcessId;
  32. } SYSTEM_PROCESS_INFO, * PSYSTEM_PROCESS_INFO;

  33. struct CONTROL_DATA
  34. {
  35.     BOOLEAN Enable_BossInvincible;
  36.     BOOLEAN Enable_NoDelay;
  37.     DWORD NoDelayValue;
  38. };

  39. CONTROL_DATA g_controlData{ 0 };

  40. typedef union tagpfnNtQuerySystemInformation {
  41.     NTSTATUS(NTAPI* func_ptr)(
  42.         IN      SYSTEM_INFORMATION_CLASS SystemInformationClass,
  43.         IN OUT  PVOID SystemInformation,
  44.         IN      ULONG SystemInformationLength,
  45.         OUT     PULONG ReturnLength OPTIONAL
  46.         );
  47. } pfnNtQuerySystemInformation;

  48. pfnNtQuerySystemInformation pNtQuerySystemInformation = { 0 };

  49. void mylog(LPCWSTR Format, ...)
  50. {
  51.     WCHAR buf[1024] = L"";
  52.     va_list args;
  53.     va_start(args, Format);
  54.     vswprintf_s(buf, _countof(buf), Format, args);
  55.     OutputDebugStringW(buf);
  56.     va_end(args);
  57. }

  58. NTSTATUS NtQuerySystemInformation_Hook(
  59.     SYSTEM_INFORMATION_CLASS SystemInformationClass,
  60.     PVOID SystemInformation,
  61.     ULONG SystemInformationLength,
  62.     PULONG ReturnLength)
  63. {
  64.     NTSTATUS Status;
  65.     PSYSTEM_PROCESS_INFO SystemProcess;
  66.     PSYSTEM_PROCESS_INFO NextSystemProcess;
  67.     Status = pNtQuerySystemInformation.func_ptr(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
  68.     if (NT_SUCCESS(Status) && SystemInformationClass == SystemProcessInformation)
  69.     {
  70.         SystemProcess = (PSYSTEM_PROCESS_INFO)SystemInformation;
  71.         NextSystemProcess = (PSYSTEM_PROCESS_INFO)((PBYTE)SystemProcess + SystemProcess->NextEntryOffset);
  72.         my_log("Query ProcessId=%llu ImageName=%wZ", NextSystemProcess->ProcessId, &NextSystemProcess->ImageName);
  73.     }
  74.     return Status;
  75. }

  76. extern "C"
  77. {
  78.     DWORD64 g_controlData_Enable_BossInvincible = 0;
  79.     DWORD64 g_controlData_Enable_NoDelay = 0;
  80.     DWORD64 g_controlData_NoDelayValue = 0;

  81.     void BossInvincible();
  82.     void AttackNoDelay();
  83.     NTSTATUS NtQuerySystemInformation_Orig(
  84.         SYSTEM_INFORMATION_CLASS SystemInformationClass,
  85.         PVOID SystemInformation,
  86.         ULONG SystemInformationLength,
  87.         PULONG ReturnLength);
  88. }

  89. void WriteMem(const DWORD64 lpAddress, PBYTE Buffer, unsigned Length)
  90. {
  91.     BOOL res;
  92.     DWORD OldProtection;
  93.     res = VirtualProtect((LPVOID)lpAddress, Length, PAGE_EXECUTE_READWRITE, &OldProtection);
  94.     if (res == TRUE)
  95.     {
  96.         memcpy((LPBYTE)lpAddress, Buffer, Length);
  97.         res = VirtualProtect((LPVOID)lpAddress, Length, OldProtection, &OldProtection);
  98.         if (res != TRUE)
  99.         {
  100.             my_log("Restore mem protect fail %lu", GetLastError());
  101.         }
  102.     }
  103.     else
  104.     {
  105.         my_log("Set mem protect fail %lu", GetLastError());
  106.     }
  107. }

  108. void AsmJumpFar(const DWORD64 lpAddress, LPCVOID Function, SIZE_T Nops)
  109. {
  110.     DWORD OldProtection;
  111.     VirtualProtect((LPVOID)lpAddress, 14ULL + Nops, PAGE_EXECUTE_READWRITE, &OldProtection);
  112.     *(LPWORD)lpAddress = 0x25FFU;
  113.     *(PDWORD)(lpAddress + 2) = 0;
  114.     *(PDWORD64)(lpAddress + 6) = (DWORD64)Function;
  115.     if (!!Nops)
  116.     {
  117.         memset(((LPBYTE)lpAddress + 14), 0x90, Nops);
  118.     }
  119.     VirtualProtect((LPVOID)lpAddress, 14ULL + Nops, OldProtection, &OldProtection);
  120. }

  121. void SetBossInvincibleEnable(BOOLEAN Enable)
  122. {
  123.     g_controlData.Enable_BossInvincible = Enable;
  124. }

  125. void SetAttackNoDelay(BOOLEAN Enable)
  126. {
  127.     g_controlData.Enable_NoDelay = Enable;
  128. }

  129. void SetAttackNoDelayValue(DWORD Value)
  130. {
  131.     g_controlData.NoDelayValue = Value;
  132. }

  133. void MyRoutine()
  134. {
  135.     g_controlData_Enable_BossInvincible = (DWORD64)RtlOffsetToPointer(&g_controlData, FIELD_OFFSET(CONTROL_DATA, Enable_BossInvincible));
  136.     g_controlData_Enable_NoDelay = (DWORD64)RtlOffsetToPointer(&g_controlData, FIELD_OFFSET(CONTROL_DATA, Enable_NoDelay));
  137.     g_controlData_NoDelayValue = (DWORD64)RtlOffsetToPointer(&g_controlData, FIELD_OFFSET(CONTROL_DATA, NoDelayValue));
  138.    
  139.     HMODULE ntdll = GetModuleHandleA("ntdll.dll");
  140.     if (ntdll)
  141.     {
  142.         DWORD64 NtQuerySystemInformation_Addr = (DWORD64)GetProcAddress(ntdll, "NtQuerySystemInformation");
  143.         *(DWORD64*)(&pNtQuerySystemInformation) = (DWORD64)NtQuerySystemInformation_Orig;
  144.         my_log("NtQuerySystemInformation_Addr=%p", NtQuerySystemInformation_Addr);
  145.         AsmJumpFar(NtQuerySystemInformation_Addr, NtQuerySystemInformation_Hook, 2);
  146.     }
  147.     else
  148.     {
  149.         my_log("Get ntdll module handle fail %lu", GetLastError());
  150.     }

  151.     BYTE bypassPatch[] =
  152.     {
  153.         //xor eax,eax
  154.         0x31, 0xC0,
  155.         //ret
  156.         0xC3,
  157.         // nops
  158.         0x90, 0x90
  159.     };
  160.     DWORD64 function_addr = 0x143B7E0E0U;
  161.     WriteMem(function_addr, bypassPatch, sizeof(bypassPatch));
  162.     AsmJumpFar(0x141B01AD0U, BossInvincible, 0);
  163.     AsmJumpFar(0x1434F9CC9U, AttackNoDelay, 0);
  164.     SetAttackNoDelayValue(5);
  165.     SetBossInvincibleEnable(FALSE);
  166.     SetAttackNoDelay(FALSE);
  167. }

  168. BOOL APIENTRY DllMain( HMODULE hModule,
  169.                        DWORD  ul_reason_for_call,
  170.                        LPVOID lpReserved
  171.                      )
  172. {
  173.     DWORD len;
  174.     WCHAR processName[MAX_PATH] = { 0 };

  175.     switch (ul_reason_for_call)
  176.     {
  177.     case DLL_PROCESS_ATTACH:
  178.         len = GetModuleFileNameW(GetModuleHandleA(NULL), processName, MAX_PATH);
  179.         if (len > 0)
  180.         {
  181.             if (StrStrW(processName, TARGET_PROCESS_NAME))
  182.             {
  183.                 my_log("CreateThread");
  184.                 CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MyRoutine, 0, 0, 0);
  185.             }
  186.         }
  187.         else
  188.         {
  189.             my_log("Get moudle file name fail %lu.", GetLastError());
  190.         }
  191.         break;
  192.     case DLL_PROCESS_DETACH:
  193.         FreeLibrary(hModule);
  194.         break;
  195.     }
  196.     return TRUE;
  197. }
複製代碼
X64AsmSample.sln
  1. Microsoft Visual Studio Solution File, Format Version 12.00
  2. # Visual Studio Version 16
  3. VisualStudioVersion = 16.0.31911.196
  4. MinimumVisualStudioVersion = 10.0.40219.1
  5. Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X64AsmSample", "X64AsmSample.vcxproj", "{BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}"
  6. EndProject
  7. Global
  8.         GlobalSection(SolutionConfigurationPlatforms) = preSolution
  9.                 Debug|x64 = Debug|x64
  10.                 Release|x64 = Release|x64
  11.         EndGlobalSection
  12.         GlobalSection(ProjectConfigurationPlatforms) = postSolution
  13.                 {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Debug|x64.ActiveCfg = Debug|x64
  14.                 {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Debug|x64.Build.0 = Debug|x64
  15.                 {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Release|x64.ActiveCfg = Release|x64
  16.                 {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Release|x64.Build.0 = Release|x64
  17.         EndGlobalSection
  18.         GlobalSection(SolutionProperties) = preSolution
  19.                 HideSolutionNode = FALSE
  20.         EndGlobalSection
  21.         GlobalSection(ExtensibilityGlobals) = postSolution
  22.                 SolutionGuid = {CB2CD138-098F-465E-A9B3-17033E4BA7F0}
  23.         EndGlobalSection
  24. EndGlobal
複製代碼
X64AsmSample.vcxproj
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3.   <ItemGroup Label="ProjectConfigurations">
  4.     <ProjectConfiguration Include="Debug|x64">
  5.       <Configuration>Debug</Configuration>
  6.       <Platform>x64</Platform>
  7.     </ProjectConfiguration>
  8.     <ProjectConfiguration Include="Release|x64">
  9.       <Configuration>Release</Configuration>
  10.       <Platform>x64</Platform>
  11.     </ProjectConfiguration>
  12.   </ItemGroup>
  13.   <PropertyGroup Label="Globals">
  14.     <VCProjectVersion>16.0</VCProjectVersion>
  15.     <Keyword>Win32Proj</Keyword>
  16.     <ProjectGuid>{be72125f-805e-4df1-b8be-80dfc1c1aa83}</ProjectGuid>
  17.     <RootNamespace>X64AsmSample</RootNamespace>
  18.     <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  19.   </PropertyGroup>
  20.   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  21.   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
  22.     <ConfigurationType>DynamicLibrary</ConfigurationType>
  23.     <UseDebugLibraries>true</UseDebugLibraries>
  24.     <PlatformToolset>v142</PlatformToolset>
  25.     <CharacterSet>Unicode</CharacterSet>
  26.   </PropertyGroup>
  27.   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
  28.     <ConfigurationType>DynamicLibrary</ConfigurationType>
  29.     <UseDebugLibraries>false</UseDebugLibraries>
  30.     <PlatformToolset>v142</PlatformToolset>
  31.     <WholeProgramOptimization>true</WholeProgramOptimization>
  32.     <CharacterSet>Unicode</CharacterSet>
  33.   </PropertyGroup>
  34.   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  35.   <ImportGroup Label="ExtensionSettings">
  36.     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
  37.   </ImportGroup>
  38.   <ImportGroup Label="Shared">
  39.   </ImportGroup>
  40.   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
  41.     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  42.   </ImportGroup>
  43.   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  44.     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  45.   </ImportGroup>
  46.   <PropertyGroup Label="UserMacros" />
  47.   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
  48.     <LinkIncremental>true</LinkIncremental>
  49.   </PropertyGroup>
  50.   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  51.     <LinkIncremental>false</LinkIncremental>
  52.   </PropertyGroup>
  53.   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
  54.     <ClCompile>
  55.       <WarningLevel>Level3</WarningLevel>
  56.       <SDLCheck>true</SDLCheck>
  57.       <PreprocessorDefinitions>_DEBUG;X64ASMSAMPLE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  58.       <ConformanceMode>true</ConformanceMode>
  59.       <PrecompiledHeader>NotUsing</PrecompiledHeader>
  60.       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
  61.     </ClCompile>
  62.     <Link>
  63.       <SubSystem>Windows</SubSystem>
  64.       <GenerateDebugInformation>true</GenerateDebugInformation>
  65.       <EnableUAC>false</EnableUAC>
  66.     </Link>
  67.   </ItemDefinitionGroup>
  68.   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  69.     <ClCompile>
  70.       <WarningLevel>Level3</WarningLevel>
  71.       <FunctionLevelLinking>true</FunctionLevelLinking>
  72.       <IntrinsicFunctions>true</IntrinsicFunctions>
  73.       <SDLCheck>true</SDLCheck>
  74.       <PreprocessorDefinitions>NDEBUG;X64ASMSAMPLE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  75.       <ConformanceMode>true</ConformanceMode>
  76.       <PrecompiledHeader>NotUsing</PrecompiledHeader>
  77.       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
  78.     </ClCompile>
  79.     <Link>
  80.       <SubSystem>Windows</SubSystem>
  81.       <EnableCOMDATFolding>true</EnableCOMDATFolding>
  82.       <OptimizeReferences>true</OptimizeReferences>
  83.       <GenerateDebugInformation>true</GenerateDebugInformation>
  84.       <EnableUAC>false</EnableUAC>
  85.     </Link>
  86.   </ItemDefinitionGroup>
  87.   <ItemGroup>
  88.     <ClCompile Include="dllmain.cpp" />
  89.   </ItemGroup>
  90.   <ItemGroup>
  91.     <MASM Include="Assembly.asm">
  92.       <FileType>Document</FileType>
  93.     </MASM>
  94.   </ItemGroup>
  95.   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  96.   <ImportGroup Label="ExtensionTargets">
  97.     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
  98.   </ImportGroup>
  99. </Project>
複製代碼
X64AsmSample.vcxproj.filters
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3.   <ItemGroup>
  4.     <Filter Include="Source Files">
  5.       <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
  6.       <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
  7.     </Filter>
  8.     <Filter Include="Header Files">
  9.       <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
  10.       <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
  11.     </Filter>
  12.     <Filter Include="Resource Files">
  13.       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
  14.       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
  15.     </Filter>
  16.   </ItemGroup>
  17.   <ItemGroup>
  18.     <ClCompile Include="dllmain.cpp">
  19.       <Filter>Source Files</Filter>
  20.     </ClCompile>
  21.   </ItemGroup>
  22.   <ItemGroup>
  23.     <MASM Include="Assembly.asm">
  24.       <Filter>Source Files</Filter>
  25.     </MASM>
  26.   </ItemGroup>
  27. </Project>
複製代碼

作者: 廖信翔    時間: 2022-2-27 16:12
提示: 作者被禁止或刪除 內容自動屏蔽
作者: xlChen    時間: 2022-2-27 23:00
太强了
作者: 依然卡卡    時間: 2022-3-14 21:55
大大 其他数据怎么改
作者: molina1026    時間: 2022-3-20 12:52
謝謝大大用心推!
作者: sky40112    時間: 2022-3-20 13:36
請問這是需要使用DLL注入的方式嗎?
DLL注入會失敗
目前可以編譯完成,但不知道要怎麼使用
作者: strays    時間: 2022-3-21 13:42
建議 使用intel c++
作者: sky40112    時間: 2022-3-21 17:20
strays 發表於 2022-3-21 13:42
建議 使用intel c++

怎麼說呢?? 是有比較好debug 還是說有其方便之處
平常都是用visual studio 寫 C++ & C#
VSC++ 加入 masm 不是也可以編寫嗎?

作者: strays    時間: 2022-3-21 17:33
測試下intel c++
作者: Happy0626    時間: 2022-3-24 22:16
還是看不懂 求高手來個教學
作者: huhai122    時間: 2022-4-18 20:34
太专业了.有点弄不来怎么玩
作者: Torin    時間: 2022-6-19 16:01
sky40112 發表於 2022-3-21 17:20
怎麼說呢?? 是有比較好debug 還是說有其方便之處
平常都是用visual studio 寫 C++ & C#
VSC++ 加入 masm  ...

inline asm 方便
作者: t812206236    時間: 2022-7-9 19:08
  1. #define FIELD_OFFSET(type, field)    ((LONG)(LONG_PTR)&(((type *)0)->field))
複製代碼
令人眼前一亮
作者: PS2GUARD    時間: 2022-7-20 22:31
感謝分享
作者: ysl86294    時間: 2023-1-5 23:54
實用
作者: 林男    時間: 2023-1-14 19:10
太厲害了
作者: kibr    時間: 2023-5-21 15:17
感谢分享
作者: JonasDai    時間: 2023-8-26 12:56
不知道为什么编译失败,是ide版本问题吗?




歡迎光臨 冰楓論壇 (https://bingfong.com/) Powered by 冰楓