zoukankan      html  css  js  c++  java
  • 使用 VS2012 开发 IDA GUI 插件 WIN32 SDK 和 内置函数 AskUsingForm_c

    1. 执行菜单的File->New->Project… (Ctrl-Shift-N)打开新建工程窗口。 

    2. 展开左侧的Visual C++项目模板分支,然后选择右侧的Win32 Project条目,输入工程名称,然后点击确定。

    3.出现Win32Application Wizard

    4. 使用默认设置

    5. 生成的文件夹及文件

    6. VS 解决方案资源管理器视图

    7. 运行结果

    8. 修改项目属性 - 选择所有配置 

    常规 将目标文件扩展名修改为.plw 配置类型 动态库(.dll)

    C/C++->常规 附加包含目录添加ida sdk include目录,例如 D:IDA64IDASDK64Include 

    C/C++->预处理器,添加__NT__;__IDP__字段到预处理器定义中。 

    C/C++->代码生成,关闭安全检查

    连接器->输入,将 ida.lib 添加到附加依赖项中。C:IDA64idasdk64libx86_win_vc_32ida.lib

    连接器->命令行添加/EXPORT:PLUGIN 

    生成事件->后期生成事件,将生成的文件复制到 ida 插件目录

    xcopy /c /d /r /y "$(TargetPath)" "D:IDA64plugins"

     8. 新建配置用于调试 EXE

    修改配置属性 -

    常规 将目标文件扩展名修改为.exe 配置类型 应用程序(.exe)

    连接器->命令行删除 /EXPORT:PLUGIN 

    生成事件->后期生成事件,删除 copy /c /d /r /y "$(TargetPath)" "D:IDA64plugins"

    C/C++->预处理器,添加_DEBUG_EXE 字段到预处理器定义中。 

    8. 添加新文件 ida_plug_main.cpp

     

    ida_plug_main.cpp

    #include "stdafx.h"
    
    int __stdcall IDAP_init ( void )
    {
      // Do checks here to ensure your plug-in is being used within
      // an environment it was written for. Return PLUGIN_SKIP if the
      // checks fail, otherwise return PLUGIN_KEEP.
      return ( PLUGIN.flags & PLUGIN_UNL ) ? PLUGIN_OK : PLUGIN_KEEP;
    }
    
    void __stdcall IDAP_term ( void )
    {
      // Stuff to do when exiting, generally you'd put any sort
      // of clean-up jobs here.
      return;
    }
    
    // The plugin can be passed an integer argument from the plugins.cfg
    // file. This can be useful when you want the one plug-in to do
    // something different depending on the hot-key pressed or menu
    // item selected.
    void __stdcall IDAP_run ( int arg )
    {
      // The "meat" of your plug-in
      msg ( "ida plug-in run!
    " );
    }
    
    // There isn't much use for these yet, but I set them anyway.
    char IDAP_comment[]   = "ida plug-in template";
    char IDAP_help[]    = "ida plug-in template";
    
    // The name of the plug-in displayed in the Edit->Plugins menu. It can
    // be overridden in the user's plugins.cfg file.
    char IDAP_name[]    = "ida plug-in template";
    
    // The hot-key the user can use to run your plug-in.
    char IDAP_hotkey[]  = "Ctrl-Alt-X";
    
    // The all-important exported PLUGIN object
    plugin_t PLUGIN =
    {
      IDP_INTERFACE_VERSION,  // IDA version plug-in is written for
      PLUGIN_UNL,     // Flags (see below)
      IDAP_init,      // Initialisation function
      IDAP_term,      // Clean-up function
      IDAP_run,       // Main plug-in body
      IDAP_comment,   // Comment unused
      IDAP_help,      // As above unused
      IDAP_name,      // Plug-in name shown in
      IDAP_hotkey     // Hot key to run the plug-in
    };

    修改 "stdafx.h" 文件, 添加 ida sdk 头文件

    // stdafx.h : 标准系统包含文件的包含文件,
    // 或是经常使用但不常更改的
    // 特定于项目的包含文件
    //
    
    #pragma once
    
    #include "targetver.h"
    
    #define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息
    // Windows 头文件:
    #include <windows.h>
    
    // C 运行时头文件
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <tchar.h>
    
    
    // TODO: 在此处引用程序需要的其他头文件
    #include <ida.hpp>
    
    #include <idp.hpp>
    #include <loader.hpp>
    #include <kernwin.hpp>
    
    #include <area.hpp>
    #include <segment.hpp>
    #include <funcs.hpp>
    #include <lines.hpp>
    #include <srarea.hpp>
    
    #include <ua.hpp>
    #include <xref.hpp>
    #include <offset.hpp>
    #include <bytes.hpp>
    #include <name.hpp>
    #include <enum.hpp>
    #include <struct.hpp>

     现在通过VS2012调试 ida_plugin_template.exe, 提示 : 无法启动此程序,因为计算机中丢失 IDA.WLL。尝试重新安装该程序以解决此问题。 

    复制 D:IDA64 文件夹中的 ida.wll 到 ida_plugin_template.exe 所在文件夹 D:workspace_c++ida_sdk_projectsida_plugin_templateDebugExe 即可调试

    ida_plugin_template.plw 也可以被 ida 加载 < Ctrl-Alt-X >

    ida 输出 //  msg ( "ida plug-in run! " );

    在 ida_plug_main.cpp 源代码中设置断点, 然后使用 VS2012 工具 - 附加到进程...

    选择 idaq.exe 即可调试 ida_plugin_template.plw

    现在再次调用插件, 会在设置的断点处停下来, 等待调试

    修改   ida_plug_main.cpp  和 ida_plugin_template.cpp 使插件显示 GUI 窗口

    同时修改 D:IDA64pluginsplugins.cfg 可是传入不同的参数给插件

                     ida_plugin_template_0                     ida_plugin_template    Ctrl-Alt-0    0
                     ida_plugin_template_1                     ida_plugin_template    Ctrl-Alt-1    1

      

    #include "stdafx.h"
    
    int __stdcall IDAP_init ( void )
    {
      // Do checks here to ensure your plug-in is being used within
      // an environment it was written for. Return PLUGIN_SKIP if the
      // checks fail, otherwise return PLUGIN_KEEP.
      return ( PLUGIN.flags & PLUGIN_UNL ) ? PLUGIN_OK : PLUGIN_KEEP;
    }
    
    void __stdcall IDAP_term ( void )
    {
      // Stuff to do when exiting, generally you'd put any sort
      // of clean-up jobs here.
      return;
    }
    
    void __stdcall IDAP_run ( int arg );
    
    
    // There isn't much use for these yet, but I set them anyway.
    char IDAP_comment[]   = "ida plug-in template";
    char IDAP_help[]    = "ida plug-in template";
    
    // The name of the plug-in displayed in the Edit->Plugins menu. It can
    // be overridden in the user's plugins.cfg file.
    char IDAP_name[]    = "ida plug-in template";
    
    // The hot-key the user can use to run your plug-in.
    char IDAP_hotkey[]  = "Ctrl-Alt-X";
    
    // The all-important exported PLUGIN object
    plugin_t PLUGIN =
    {
      IDP_INTERFACE_VERSION,  // IDA version plug-in is written for
      PLUGIN_UNL,     // Flags (see below)
      IDAP_init,      // Initialisation function
      IDAP_term,      // Clean-up function
      IDAP_run,       // Main plug-in body
      IDAP_comment,   // Comment unused
      IDAP_help,      // As above unused
      IDAP_name,      // Plug-in name shown in
      IDAP_hotkey     // Hot key to run the plug-in
    };
    
    //------------------------------------------------------------------------------------- BOOL CALLBACK EnumIdaMainWindow ( HWND hwnd, LPARAM lParam ) { WINDOWINFO winInfo; DWORD dwIdaProcessId
    = * ( ( DWORD* ) lParam ); DWORD dwProcessId; GetWindowThreadProcessId ( hwnd, &dwProcessId ); winInfo.cbSize = sizeof ( WINDOWINFO ); GetWindowInfo ( hwnd, &winInfo ); if ( dwProcessId == dwIdaProcessId && GetParent ( hwnd ) == NULL && winInfo.dwStyle & WS_VISIBLE ) { * ( ( HWND * ) lParam ) = hwnd; return FALSE; // stop EnumWindow() } return TRUE; }
    //------------------------------------------------------------------------------------ HWND GetIdaMainWindow (
    void ) { DWORD dwIdaProcessId = GetCurrentProcessId(); if ( !EnumWindows ( EnumIdaMainWindow, ( LPARAM ) &dwIdaProcessId ) ) { return ( HWND ) dwIdaProcessId; } return NULL; } HWND GetIdaMainWindow ( void ); int APIENTRY _tWinMain ( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow ); // The plugin can be passed an integer argument from the plugins.cfg // file. This can be useful when you want the one plug-in to do // something different depending on the hot-key pressed or menu // item selected. void __stdcall IDAP_run ( int arg ) { // The "meat" of your plug-in msg ( "ida plug-in run! " );
    HWND hIdaMainWindow
    = GetIdaMainWindow(); if ( hIdaMainWindow == NULL ) return; switch ( arg ) { case 0: case 1: _tWinMain ( NULL, ( HINSTANCE ) hIdaMainWindow, ( LPWSTR ) arg, SW_SHOWNORMAL ); break; default: break; } }
    // ida_plugin_template.cpp : 定义应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "ida_plugin_template.h"
    
    #define MAX_LOADSTRING 100
    
    // 全局变量:
    HINSTANCE hInst;                // 当前实例
    TCHAR szTitle[MAX_LOADSTRING];          // 标题栏文本
    TCHAR szWindowClass[MAX_LOADSTRING];      // 主窗口类名
    
    // 此代码模块中包含的函数的前向声明:
    ATOM        MyRegisterClass ( HINSTANCE hInstance );
    BOOL        InitInstance ( HINSTANCE, int );
    LRESULT CALLBACK  WndProc ( HWND, UINT, WPARAM, LPARAM );
    INT_PTR CALLBACK  About ( HWND, UINT, WPARAM, LPARAM );
    
    HWND hIdaMainWindow = NULL;                                                       
    int idaArg;                                                                       
    
    int APIENTRY _tWinMain (
      _In_ HINSTANCE hInstance,
      _In_opt_ HINSTANCE hPrevInstance,
      _In_ LPTSTR    lpCmdLine,
      _In_ int       nCmdShow )
    {
      UNREFERENCED_PARAMETER ( hPrevInstance );
      UNREFERENCED_PARAMETER ( lpCmdLine );
      // TODO: 在此放置代码。
      //
    #ifndef _DEBUG_EXE
      
    //
      if ( hInstance == NULL )
      {
        hInstance = GetModuleHandle ( L"ida_plugin_template.plw" );
        
        if ( hInstance == NULL )
          return 0;
          
        idaArg = ( int ) lpCmdLine;
        hIdaMainWindow = ( HWND ) hPrevInstance;
      }
      
    #endif

    MSG msg; HACCEL hAccelTable; // 初始化全局字符串 LoadString ( hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); LoadString ( hInstance, IDC_IDA_PLUGIN_TEMPLATE, szWindowClass, MAX_LOADSTRING ); MyRegisterClass ( hInstance ); // 执行应用程序初始化: if ( !InitInstance ( hInstance, nCmdShow ) ) return FALSE; hAccelTable = LoadAccelerators ( hInstance, MAKEINTRESOURCE ( IDC_IDA_PLUGIN_TEMPLATE ) ); // 主消息循环: // retrieves a message other than WM_QUIT BOOL bRet; while ( ( bRet = GetMessage ( &msg, NULL, 0, 0 ) ) != 0 ) { if ( bRet == - 1 ) break; if ( !TranslateAccelerator ( msg.hwnd, hAccelTable, &msg ) ) { TranslateMessage ( &msg ); DispatchMessage ( &msg ); } } // retrieves the WM_QUIT message // or hWnd is an invalid window handle or lpMsg is an invalid pointer. // return ( int ) msg.wParam; // WM_QUIT wParam } // // 函数: MyRegisterClass() // // 目的: 注册窗口类。 // ATOM MyRegisterClass ( HINSTANCE hInstance ) { WNDCLASSEX wcex; wcex.cbSize = sizeof ( WNDCLASSEX ); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon ( hInstance, MAKEINTRESOURCE ( IDI_IDA_PLUGIN_TEMPLATE ) ); wcex.hCursor = LoadCursor ( NULL, IDC_ARROW ); wcex.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 ); wcex.lpszMenuName = MAKEINTRESOURCE ( IDC_IDA_PLUGIN_TEMPLATE ); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon ( wcex.hInstance, MAKEINTRESOURCE ( IDI_SMALL ) ); return RegisterClassEx ( &wcex ); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitInstance ( HINSTANCE hInstance, int nCmdShow ) { HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow ( szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
    hIdaMainWindow,
    NULL, hInstance, NULL );
    if ( !hWnd )
      {
        return FALSE;
      }
      
      ShowWindow ( hWnd, nCmdShow );
      UpdateWindow ( hWnd );
      return TRUE;
    }
    
    //
    //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  目的: 处理主窗口的消息。
    //
    //  WM_COMMAND  - 处理应用程序菜单
    //  WM_PAINT  - 绘制主窗口
    //  WM_DESTROY  - 发送退出消息并返回
    //
    //
    LRESULT CALLBACK WndProc ( HWND hWnd, UINT message, WPARAM wParam,
                               LPARAM lParam )
    {
      int wmId, wmEvent;
      PAINTSTRUCT ps;
      HDC hdc;
      
      switch ( message )
      {
        case WM_COMMAND:
          wmId    = LOWORD ( wParam );
          wmEvent = HIWORD ( wParam );
          
          // 分析菜单选择:
          switch ( wmId )
          {
            case IDM_ABOUT:
              DialogBox ( hInst, MAKEINTRESOURCE ( IDD_ABOUTBOX ), hWnd, About );
              break;
              
            case IDM_EXIT:
              DestroyWindow ( hWnd );
              break;
              
            default:
              return DefWindowProc ( hWnd, message, wParam, lParam );
          }
          
          break;
          
        case WM_PAINT:
          hdc = BeginPaint ( hWnd, &ps );
          // TODO: 在此添加任意绘图代码...
          EndPaint ( hWnd, &ps );
          break;
          
        case WM_CREATE:                                                            
          if ( hIdaMainWindow )
            EnableWindow ( hIdaMainWindow, FALSE );
            
          break;
          
        case WM_DESTROY:                                                           
          if ( hIdaMainWindow )
            EnableWindow ( hIdaMainWindow, TRUE );
            
          PostQuitMessage ( 0 ); // WM_QUIT, wParam = 0
          break;
          
        default:
          return DefWindowProc ( hWnd, message, wParam, lParam );
      }
      
      return 0;
    }
    
    // “关于”框的消息处理程序。
    INT_PTR CALLBACK About ( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
    {
      UNREFERENCED_PARAMETER ( lParam );
      
      switch ( message )
      {
        case WM_INITDIALOG:
          return ( INT_PTR ) TRUE;
          
        case WM_COMMAND:
          if ( LOWORD ( wParam ) == IDOK || LOWORD ( wParam ) == IDCANCEL )
          {
            EndDialog ( hDlg, LOWORD ( wParam ) );
            return ( INT_PTR ) TRUE;
          }
          
          break;
      }
      
      return ( INT_PTR ) FALSE;
    }

    修改   ida_plug_main.cpp  使用内置的界面显示

    static void __stdcall AskUsingForm ( void );
    
    // The plugin can be passed an integer argument from the plugins.cfg
    // file. This can be useful when you want the one plug-in to do
    // something different depending on the hot-key pressed or menu
    // item selected.
    void __stdcall IDAP_run ( int arg )
    {
      // The "meat" of your plug-in
      msg ( "ida plug-in run!
    " );
      HWND hIdaMainWindow = GetIdaMainWindow();
      
      if ( hIdaMainWindow == NULL )
        return;
        
      switch ( arg )
      {
        case 0:
          _tWinMain ( NULL, ( HINSTANCE ) hIdaMainWindow, ( LPWSTR ) arg, SW_SHOWNORMAL );
          break;
          
        case 1:
          AskUsingForm();
          break;
          
        default:
          break;
      }
    }
    
    static const char *dialog1 = //
      "This is the title
    
    "// dialog title
      "<##Radio Buttons##Radio 1:R>
    "
      "<Radio 2:R>>
    "//ushort* number of selected radio
      "<##Radio Buttons##Radio 1:R>
    "
      "<Radio 2:R>>
    "//ushort* number of selected radio
      "<##Check Boxes##Check 1:C>
    "
      "<Check 2:C>>
    "//ushort* bitmask of checks
      "<##Check Boxes##Check 1:C>
    "
      "<Check 2:C>>
    ";//ushort* bitmask of checks
    
    static void __stdcall AskUsingForm ( void )
    {
      ushort bitMask, bitMask1 = 0;
      ushort btnIndex, bitIndex1;
      int ok = AskUsingForm_c ( dialog1, &btnIndex, &bitIndex1, &bitMask, &bitMask1 );
    }

  • 相关阅读:
    轻松学MVC4.0–6 MVC的执行流程
    (转)从零实现3D图像引擎:(12)构建支持欧拉和UVN的相机系统
    (转)从零实现3D图像引擎:(9)四元数函数库
    (转)从零实现3D图像引擎:(10)Hello3DWorld
    (转)用AGG实现高质量图形输出(二)
    (转)Direct3D新功能
    (转)从零实现3D图像引擎:(7)矩阵函数库
    (转)用AGG实现高质量图形输出(一)
    (转)从零实现3D图像引擎:(13)把宽高比、透视投影矩阵、屏幕变换矩阵说透
    (转)创业公司的CEO每周须必做的13件事
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3346643.html
Copyright © 2011-2022 走看看