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

QQ登录

只需一步,快速开始

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

如何实现windbg x64汇编功能

[复制链接]
发表于 2015-11-15 17:32:07 | 显示全部楼层 |阅读模式

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

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

×
  熟悉windbg的都知道,a指令,只支持x86,另外经我研究,虽然引擎中扩展了I386|ARM|IA64|AMD64|EBC的指令集,但是后几种只有反汇编能力,而并没有汇编能力。因此这是个突破点,然而汇编器源码这种东西是比较稀缺的,无奈之下为了实现amd64汇编我选择了ml64.exe工具,利用该用具生成机器码
目前以实现效果:
0:000> !a -s AMD64
usage: !a [-s ProcessorType] [-a Address]
        Optional ProcessorType:I386|ARM|IA64|AMD64|EBC
        Default ProcessorType is I386;Default Address is current $ip
example:!a -s AMD64 -a .
Assemble on AMD64 at 00007FFD75B81970
please input asm code, [enter] to leave
mov r8,0
mov r8,0
                           00007ffd`75b81970 49c7c000000000  mov     r8,0
mov r8,gs:[0]
mov r8,gs:[0]
                           00007ffd`75b81977 654c8b042500000000 mov   r8,qword ptr gs:[0] gs:00000000`00000000=????????????????


asm edit leave

源码:
WDbgLiExts.cpp
  1. #include "DbgEng.h"
  2. #include <windows.h>
  3. #include <fstream>
  4. #include <shlwapi.h>
  5. #pragma comment(lib,"Shlwapi.lib")

  6. #define EXT_MAJOR_VER  1
  7. #define EXT_MINOR_VER  0


  8. extern "C" HRESULT CALLBACK
  9. DebugExtensionInitialize(PULONG Version, PULONG Flags)
  10. {
  11.         *Version = DEBUG_EXTENSION_VERSION(EXT_MAJOR_VER, EXT_MINOR_VER);
  12.         *Flags = 0;  // Reserved for future use.
  13.         return S_OK;
  14. }

  15. extern "C" void CALLBACK
  16. DebugExtensionNotify(ULONG Notify, ULONG64 Argument)
  17. {
  18.         UNREFERENCED_PARAMETER(Argument);
  19.         switch (Notify) {
  20.                 // A debugging session is active. The session may not necessarily be suspended.
  21.         case DEBUG_NOTIFY_SESSION_ACTIVE:
  22.                 break;
  23.                 // No debugging session is active.
  24.         case DEBUG_NOTIFY_SESSION_INACTIVE:
  25.                 break;
  26.                 // The debugging session has suspended and is now accessible.
  27.         case DEBUG_NOTIFY_SESSION_ACCESSIBLE:
  28.                 break;
  29.                 // The debugging session has started running and is now inaccessible.
  30.         case DEBUG_NOTIFY_SESSION_INACCESSIBLE:
  31.                 break;
  32.         }
  33.         return;
  34. }

  35. extern "C" void CALLBACK
  36. DebugExtensionUninitialize(void)
  37. {
  38.         return;
  39. }

  40. HRESULT CALLBACK
  41. helloworld(PDEBUG_CLIENT pDebugClient, PCSTR args)
  42. {
  43.         UNREFERENCED_PARAMETER(args);
  44.         IDebugControl* pDebugControl;
  45.         if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl),
  46.                 (void **)&pDebugControl))) {
  47.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Hello World!\n");
  48.                 pDebugControl->Release();
  49.         }
  50.         return S_OK;
  51. }

  52. //返回参数长度,和起始位置
  53. int GetParamVal(PCSTR& begin, PCSTR& end)
  54. {
  55.         PCSTR truebegin = 0, trueend = 0;
  56.         while (*begin)
  57.         {
  58.                 if (*begin != ' ' && *begin != '\t')
  59.                 {
  60.                         truebegin = begin;
  61.                         break;
  62.                 }
  63.                 begin++;
  64.         }

  65.         trueend = truebegin;
  66.         do
  67.         {
  68.                 if (*trueend == '-' || *trueend == '\0')
  69.                 {
  70.                         break;
  71.                 }
  72.                 trueend++;
  73.         } while (true);

  74.         return trueend - truebegin;
  75. }

  76. PSTR getnextnonblank(PSTR begin)
  77. {
  78.         while (*begin)
  79.         {
  80.                 if (*begin != ' ' && *begin != '\t')
  81.                         break;
  82.                 begin++;
  83.         }
  84.         return begin;
  85. }

  86. PSTR getnextchar(PSTR begin, char ch)
  87. {
  88.         while (*begin)
  89.         {
  90.                 if (*begin == ch)
  91.                         break;
  92.                 begin++;
  93.         }
  94.         return begin;
  95. }

  96. bool ResolveSymbolInExpression(IDebugControl* pDebugControl, PSTR asmcode, PSTR outcode, ULONG64 Xip)
  97. {       
  98.         /*
  99.         //找到操作码起始位置
  100.         PSTR opcode, opdata;
  101.         int opcodelen, opdatalen;
  102.         asmcode = getnextnonblank(asmcode);
  103.         if (!*asmcode)//找不到操作码
  104.                 return false;
  105.         char si[] = " ,,,,,";
  106.         int index = 0;
  107.         char exp[256];
  108.         __debugbreak();
  109.         DEBUG_VALUE value;
  110.         do
  111.         {
  112.                 opcode = asmcode;
  113.                 asmcode = getnextchar(asmcode, si[index]);
  114.                 opcodelen = asmcode - opcode;
  115.                 strncpy(exp, opcode, opcodelen);
  116.                 exp[opcodelen] = '\0';
  117.                 memset(&value, 0, sizeof(value));
  118.                 if (SUCCEEDED(pDebugControl->Evaluate(exp, DEBUG_VALUE_INT64, &value, NULL)))
  119.                 {
  120.                         //若能解析
  121.                         sprintf(exp, "%I64d", (LONG64)value.I64);
  122.                         opcodelen = strlen(exp);
  123.                         strncpy(outcode, exp, opcodelen);
  124.                         outcode[opcodelen] = '\0';
  125.                         pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "解析exp=%s\n", outcode);
  126.                 }
  127.                 else
  128.                 {
  129.                         //不能解析
  130.                         strncpy(outcode, opcode, opcodelen);
  131.                         outcode[opcodelen] = '\0';
  132.                         pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "无法解析exp=%s\n", exp);
  133.                 }
  134.                
  135.                 outcode += opcodelen;
  136.                 asmcode = getnextnonblank(asmcode + 1);
  137.                 *outcode = si[index];
  138.                 outcode++;
  139.                 index++;
  140.         } while (*asmcode);
  141.         outcode[-1] = '\0';
  142.         */
  143.         strcpy(outcode, asmcode);
  144.         return true;
  145. }

  146. bool GetByteCode(IDebugControl* pDebugControl, PSTR asmcode, PSTR outbyte, PULONG byteswrite)
  147. {
  148.         __debugbreak();
  149.         char buf[256], asmpath[256], objpath[256], ml64path[256], msvcr100[256];
  150.         bool ret = false;
  151.         GetCurrentDirectoryA(256, buf);
  152.         sprintf(asmpath, "%s\\test.asm", buf);
  153.         sprintf(objpath, "%s\\test.obj", buf);
  154.         sprintf(ml64path, "%s\\ml64.exe", buf);
  155.         sprintf(msvcr100, "%s\\msvcr100.dll", buf);
  156.         FILE* fpasm = NULL,*fpobj = NULL;
  157.         fpasm = fopen(asmpath, "w");
  158.         if (!fpasm)
  159.         {
  160.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "无法创建asm\n");
  161.         }
  162.         else if (!PathFileExistsA(ml64path))
  163.         {
  164.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "ml64.exe不存在\n");
  165.         }
  166.         else if (!PathFileExistsA(msvcr100))
  167.         {
  168.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "msvcr100.dll不存在\n");
  169.         }
  170.         else
  171.         {
  172.                 fputs(".CODE\n", fpasm);
  173.                 fputs("Entry PROC\n", fpasm);
  174.                 fputs(asmcode, fpasm);
  175.                 fputs("\nEntry ENDP\n", fpasm);
  176.                 fputs("END\n", fpasm);
  177.                 fclose(fpasm);
  178.                 fpasm = NULL;
  179.                 if (!PathFileExistsA(objpath) || DeleteFileA(objpath))
  180.                 {
  181.                         WinExec("ml64 test.asm", SW_HIDE);
  182.                         Sleep(200);
  183.                         fpobj = fopen(objpath, "rb");
  184.                         if (!fpobj)
  185.                         {
  186.                                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "语法错误\n");
  187.                         }
  188.                         else
  189.                         {
  190.                                 char* data = new char[256];
  191.                                 fread(data, 256, 1, fpobj);
  192.                                 int offset = 0x18;
  193.                                 unsigned short datasize;
  194.                                 offset += *(unsigned short*)(data + offset);
  195.                                 datasize = *(unsigned short*)(data + 0x24);
  196.                                 //此时data+offset处的datasize个字节即为汇编生成的机器码
  197.                                 //写入内存
  198.                                 memcpy(outbyte, data + offset, datasize);
  199.                                 *byteswrite = datasize;
  200.                                 delete[]data;
  201.                                 ret = true;
  202.                         }
  203.                 }
  204.                 else
  205.                 {
  206.                         pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "obj文件无法删除\n");       
  207.                 }
  208.         }
  209.         if (fpasm)
  210.                 fclose(fpasm);
  211.         if (fpobj)
  212.                 fclose(fpobj);
  213.         //DeleteFileA(asmpath);
  214.         DeleteFileA(objpath);
  215.         return ret;
  216. }

  217. HRESULT CALLBACK
  218. a(PDEBUG_CLIENT pDebugClient, PCSTR args)
  219. {
  220.         UNREFERENCED_PARAMETER(args);
  221.         IDebugControl* pDebugControl;

  222.         if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl),(void **)&pDebugControl)))
  223.         {
  224.                 HRESULT result = 0;
  225.                 ULONG OriProcessorType = 0, CurProcessorType = 0;
  226.                 if (!SUCCEEDED(pDebugControl->GetEffectiveProcessorType(&OriProcessorType)))
  227.                         OriProcessorType = IMAGE_FILE_MACHINE_I386;

  228.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "usage: !a [-s ProcessorType] [-a Address]\n");
  229.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "\tOptional ProcessorType:I386|ARM|IA64|AMD64|EBC\n");
  230.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "\tDefault ProcessorType is I386;Default Address is current $ip\n");
  231.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "example:!a -s AMD64 -a .\n");

  232.                 PSTR pt = (PSTR)args;
  233.                 DEBUG_VALUE value;
  234.                 ULONG64 Address;

  235.                 char exp[256] = "$ip",ProcessorName[256];
  236.                 PCSTR b = pt, e = pt;
  237.                 CurProcessorType = IMAGE_FILE_MACHINE_I386;
  238.                 strcpy(ProcessorName, "I386");
  239.                 if (b = strstr(pt, "-s"))
  240.                 {
  241.                         if (strstr(pt, "I386"))
  242.                         {
  243.                                 CurProcessorType = IMAGE_FILE_MACHINE_I386;
  244.                                 strcpy(ProcessorName, "I386");
  245.                         }
  246.                         else if (strstr(pt, "ARM"))
  247.                         {
  248.                                 CurProcessorType = IMAGE_FILE_MACHINE_ARM;
  249.                                 strcpy(ProcessorName, "ARM");
  250.                         }
  251.                         else if (strstr(pt, "IA64"))
  252.                         {
  253.                                 CurProcessorType = IMAGE_FILE_MACHINE_IA64;
  254.                                 strcpy(ProcessorName, "IA64");
  255.                         }
  256.                         else if (strstr(pt, "AMD64"))
  257.                         {
  258.                                 CurProcessorType = IMAGE_FILE_MACHINE_AMD64;
  259.                                 strcpy(ProcessorName, "AMD64");
  260.                         }
  261.                         else if (strstr(pt, "EBC"))
  262.                         {
  263.                                 CurProcessorType = IMAGE_FILE_MACHINE_EBC;
  264.                                 strcpy(ProcessorName, "EBC");
  265.                         }
  266.                 }
  267.                 else if (b = strstr(pt, "-a"))
  268.                 {
  269.                         e = b;
  270.                         int len = GetParamVal(b, e);
  271.                         if (len)
  272.                         {
  273.                                 strncpy(exp, b, len);
  274.                                 exp[len] = '\0';
  275.                         }
  276.                 }
  277.                 pDebugControl->Evaluate(exp, (OriProcessorType == IMAGE_FILE_MACHINE_I386) ? DEBUG_VALUE_INT32 : DEBUG_VALUE_INT64, &value, NULL);
  278.                 Address = (OriProcessorType == IMAGE_FILE_MACHINE_I386) ? value.I32 : value.I64;       
  279.                 pDebugControl->SetEffectiveProcessorType(CurProcessorType);
  280.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Assemble on %s at %N\n please input asm code, [enter] to leave\n", ProcessorName, Address);

  281.                 char Inputbuf[256];
  282.                 while (true)
  283.                 {
  284.                         ULONG64 NextAddr = Address,NextAddr2;
  285.                         memset(Inputbuf, 0, 256);
  286.                         pDebugControl->Input(Inputbuf, 256, NULL);
  287.                         if (strlen(Inputbuf) == 0)
  288.                                 break;
  289.                         switch (CurProcessorType)
  290.                         {
  291.                         case IMAGE_FILE_MACHINE_I386:
  292.                                 strcpy(pt, Inputbuf);
  293.                                 //逐行反汇编
  294.                                 result = pDebugControl->Assemble(Address, Inputbuf, &NextAddr);
  295.                                 //打印结果
  296.                                 if (SUCCEEDED(result))
  297.                                 {
  298.                                         pDebugControl->OutputDisassembly(DEBUG_OUTCTL_ALL_CLIENTS, Address, DEBUG_DISASM_EFFECTIVE_ADDRESS | DEBUG_DISASM_MATCHING_SYMBOLS |
  299.                                                 DEBUG_DISASM_SOURCE_LINE_NUMBER | DEBUG_DISASM_SOURCE_FILE_NAME, &NextAddr2);
  300.                                         Address = NextAddr;
  301.                                 }
  302.                                 break;
  303.                         case IMAGE_FILE_MACHINE_AMD64:
  304.                                 {
  305.                                         char bytecode[256],fixasmcode[256];                               
  306.                                         bool suc = true;
  307.                                        
  308.                                         //使用ml64进行解析:
  309.                                         //1.先将Inputbuf中的符号解析为数据
  310.                                         suc = ResolveSymbolInExpression(pDebugControl, Inputbuf, fixasmcode, Address);
  311.                                         if(!suc)
  312.                                                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "unresolve symbol\n");
  313.                                         //2.使用ml64解析并取得obj机器码
  314.                                         else
  315.                                         {
  316.                                                 ULONG bytewrite = 0;
  317.                                                 suc = GetByteCode(pDebugControl, fixasmcode, bytecode, &bytewrite);
  318.                                                 if(!suc || !bytewrite)
  319.                                                         pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "file op or disasm fail\n");
  320.                                                 else
  321.                                                 {
  322.                                                         //3.写入虚拟内存
  323.                                                         IDebugDataSpaces* dataspace;
  324.                                                         if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (void **)&dataspace)))
  325.                                                         {
  326.                                                                 if (!SUCCEEDED(dataspace->WriteVirtual(Address, (PVOID)bytecode, bytewrite, NULL)))
  327.                                                                 {
  328.                                                                         suc = false;
  329.                                                                         pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "can't write to memory\n");
  330.                                                                 }
  331.                                                         }
  332.                                                         else
  333.                                                         {
  334.                                                                 suc = false;
  335.                                                                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "can't obtain IDebugDataSpaces\n");
  336.                                                         }
  337.                                                         if (suc)
  338.                                                         {
  339.                                                                 pDebugControl->OutputDisassembly(DEBUG_OUTCTL_ALL_CLIENTS, Address, DEBUG_DISASM_EFFECTIVE_ADDRESS | DEBUG_DISASM_MATCHING_SYMBOLS |
  340.                                                                         DEBUG_DISASM_SOURCE_LINE_NUMBER | DEBUG_DISASM_SOURCE_FILE_NAME, &NextAddr2);
  341.                                                                 Address = NextAddr2;
  342.                                                         }
  343.                                                 }
  344.                                         }
  345.                                        
  346.                                 }
  347.                                 break;
  348.                         default:
  349.                                 break;
  350.                         }
  351.                 }
  352.                 pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "asm edit leave\n", ProcessorName, Address);
  353.                 pDebugControl->SetEffectiveProcessorType(OriProcessorType);
  354.                 pDebugControl->Release();
  355.         }
  356.         return S_OK;
  357. }
复制代码


export.def

EXPORTS
  DebugExtensionNotify
  DebugExtensionInitialize
  DebugExtensionUninitialize
  a

相关文件:

回复

使用道具 举报

 楼主| 发表于 2015-11-15 17:33:13 | 显示全部楼层
源码及用到的文件

windbg a指令实现.rar

456.71 KB, 下载次数: 9

回复 赞! 靠!

使用道具 举报

发表于 2017-9-28 19:00:29 | 显示全部楼层
好东西应该下载
回复 赞! 靠!

使用道具 举报

发表于 2020-1-30 18:33:19 | 显示全部楼层
太牛逼了。
回复

使用道具 举报

发表于 2020-12-16 23:22:52 | 显示全部楼层
输入看不懂但是感觉很6666
回复 赞! 靠!

使用道具 举报

本版积分规则

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

GMT+8, 2024-11-22 06:07 , Processed in 0.033387 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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