使用 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:\IDA64\IDASDK64\Include
C/C++->预处理器,添加__NT__;__IDP__字段到预处理器定义中。
C/C++->代码生成,关闭安全检查
连接器->输入,将 ida.lib 添加到附加依赖项中。C:\IDA64\idasdk64\lib\x86_win_vc_32\ida.lib
连接器->命令行添加/EXPORT:PLUGIN
生成事件->后期生成事件,将生成的文件复制到 ida 插件目录
xcopy /c /d /r /y "$(TargetPath)" "D:\IDA64\plugins\"
8. 新建配置用于调试 EXE
修改配置属性 -
常规 将目标文件扩展名修改为.exe 配置类型 应用程序(.exe)
连接器->命令行删除 /EXPORT:PLUGIN
生成事件->后期生成事件,删除 copy /c /d /r /y "$(TargetPath)" "D:\IDA64\plugins\"
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!\n" );
} // 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_projects\ida_plugin_template\DebugExe 即可调试
ida_plugin_template.plw 也可以被 ida 加载 < Ctrl-Alt-X >
ida 输出 // msg ( "ida plug-in run!\n" );
在 ida_plug_main.cpp 源代码中设置断点, 然后使用 VS2012 工具 - 附加到进程...
选择 idaq.exe 即可调试 ida_plugin_template.plw
现在再次调用插件, 会在设置的断点处停下来, 等待调试
修改 ida_plug_main.cpp 和 ida_plugin_template.cpp 使插件显示 GUI 窗口
同时修改 D:\IDA64\plugins\plugins.cfg 可是传入不同的参数给插件
ida_plugin_template_0 ida_plugin_template Ctrl-Alt-
ida_plugin_template_1 ida_plugin_template Ctrl-Alt-
#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!\n" );
HWND hIdaMainWindow = GetIdaMainWindow(); if ( hIdaMainWindow == NULL )
return; switch ( arg )
{
case :
case :
_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 ; 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, , ) ) != )
{
if ( bRet == - )
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 = ;
wcex.cbWndExtra = ;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon ( hInstance,
MAKEINTRESOURCE ( IDI_IDA_PLUGIN_TEMPLATE ) );
wcex.hCursor = LoadCursor ( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + );
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, , CW_USEDEFAULT, ,
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 ( ); // WM_QUIT, wParam = 0
break; default:
return DefWindowProc ( hWnd, message, wParam, lParam );
} return ;
} // “关于”框的消息处理程序。
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!\n" );
HWND hIdaMainWindow = GetIdaMainWindow(); if ( hIdaMainWindow == NULL )
return; switch ( arg )
{
case :
_tWinMain ( NULL, ( HINSTANCE ) hIdaMainWindow, ( LPWSTR ) arg, SW_SHOWNORMAL );
break; case :
AskUsingForm();
break; default:
break;
}
} static const char *dialog1 = //
"This is the title\n\n"// dialog title
"<##Radio Buttons##Radio 1:R>\n"
"<Radio 2:R>>\n"//ushort* number of selected radio
"<##Radio Buttons##Radio 1:R>\n"
"<Radio 2:R>>\n"//ushort* number of selected radio
"<##Check Boxes##Check 1:C>\n"
"<Check 2:C>>\n"//ushort* bitmask of checks
"<##Check Boxes##Check 1:C>\n"
"<Check 2:C>>\n";//ushort* bitmask of checks static void __stdcall AskUsingForm ( void )
{
ushort bitMask, bitMask1 = ;
ushort btnIndex, bitIndex1;
int ok = AskUsingForm_c ( dialog1, &btnIndex, &bitIndex1, &bitMask, &bitMask1 );
}
使用 VS2012 开发 IDA GUI 插件 WIN32 SDK 和 内置函数 AskUsingForm_c的更多相关文章
- {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...
- 【python】-- 内置函数、软件目录开发规范(代码编码风格)
内置函数 一.内置函数表格 二.内置函数演示 1.abs(x) 功能:取数的绝对值 >>> abs(-1) #取-1的绝对值 1 ########################## ...
- Python3基础(4)匿名函数、装饰器、生成器、迭代器、内置函数、json&pickle序列化、软件目录开发规范、不同目录间模块调用
---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ 1 ...
- Day05:装饰器,三元表达式,函数的递归,匿名/内置函数,迭代器,模块,开发目录
上节课复习:1.函数的对象 函数可以被当作数据取处理2.函数嵌套 嵌套调用:在调用一个函数时,函数体代码又调用了其他函数 嵌套定义:在一个函数内部又定义了另一个函数 def foo( ...
- Python学习第二阶段day1 内置函数,序列化,软件目录开发规范
内置函数 1.abs() 求绝对值 2.all() 所有元素为真才返回真 all( [1,1,2,3,-1] ) 值为True 3.any() 所有元素为假才返回假 any([0,0,0 ...
- CSIC_716_20191115【内置函数、递归、模块、软件开发规范】
内置函数 map map映射:语法结构(函数对象,可迭代对象) 依次从可迭代对象中取值,然后给函数做运算,再依次返回运算的结果. ss = map(lambda x: x + x, [1, 2, 3] ...
- python全栈开发-Day12 三元表达式、函数递归、匿名函数、内置函数
一. 三元表达式 一 .三元表达式 仅应用于: 1.条件成立返回,一个值 2.条件不成立返回 ,一个值 def max2(x,y): #普通函数定义 if x > y: return x els ...
- python全栈开发-Day13 内置函数
一.内置函数 注意:内置函数id()可以返回一个对象的身份,返回值为整数. 这个整数通常对应与该对象在内存中的位置,但这与python的具体实现有关,不应该作为对身份的定义,即不够精准,最精准的还是以 ...
- python3全栈开发-内置函数补充,反射,元类,__str__,__del__,exec,type,__call__方法
一.内置函数补充 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pass obj = Foo() print(isinstan ...
随机推荐
- Freemaker 自定义指令和函数
自定义函数和指令都可以在前台或者后台进行指定. 个人理解:指令的作用,主要是进行页面调整之后进行输出:函数的作用,主要是为了进行运算,返回运算结果供前台展示. (一) 自定义指令 使用以下格式调用自定 ...
- Tutorial 5: Relationships & Hyperlinked APIs
转载自:http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/ Tutorial 5: ...
- linux -j 4
把源码编译成可执行的二进制文件, 4为服务器内核数
- 关于U3D中的移动和旋转
关于移动,其实很简单,就是移动: 第一个参数标识移动的距离,是一个矢量:第二个参数是因为游戏对象有自己的坐标系,还有一个世界坐标系,使用的坐标系不同将导致运动的结果不同: function Trans ...
- Gradient-Based Learning Applied to Document Recognition 部分阅读
卷积网络 卷积网络用三种结构来确保移位.尺度和旋转不变:局部感知野.权值共享和时间或空间降采样.典型的leNet-5如下图所示: C1中每个特征图的每个单元和输入的25个点相连,这个5* ...
- C++的黑科技(深入探索C++对象模型)
周二面了腾讯,之前只投了TST内推,貌似就是TST面试了 其中有一个问题,“如何产生一个不能被继承的类”,这道题我反反复复只想到,将父类的构造函数私有,让子类不能调用,最后归结出一个单例模式,但面试官 ...
- 1-4 TCP/IP协议族
网络协议是在内核中实现的,socket是对tcp/ip协议的系统调用,提供以下两点功能: 1. 将应用撑血数据从用户缓冲区中复制到TCP/UDP内核发送缓冲区,以交付内核发送来的数据(比如send), ...
- 最大公约数or最小公倍数
最大公约数or最小公倍数 import org.junit.Test; public class 最大公约数or最小公倍数 { public int maxGYS(int m,int n) { int ...
- 洛谷P3857 [TJOI2008]彩灯 [线性基]
题目传送门 彩灯 题目描述 Peter女朋友的生日快到了,他亲自设计了一组彩灯,想给女朋友一个惊喜.已知一组彩灯是由一排N个独立的灯泡构成的,并且有M个开关控制它们.从数学的角度看,这一排彩灯的任何一 ...
- Vim的一些补充
查看当前路径 :pwd 切换当前路径到当前打开文件所在路径 :cd %:p:h 解释: %表示当前文件名,%:p表示包含文件名的全部路径,%:p:h表示文件所在路径(head of the full ...