Sunday, 23 February 2014

Build PyQt4 for IDA 6.1 & Python 27

My Prebuild : https://mega.co.nz/#F!IN0TCAKD!dGZdKOL1OiNVjeDqz4GzvA
You will need these packages and programs:

1. MS Visual Studio 2010
2. Python27
3. Qt 4.8.5 SDK for Windows build with QT namespace
4. Sip 4.15.3 Source
5. PyQt4 4.10.3 (newest)


1. Compile sip

- Download SIP newest version from https://pypi.python.org/pypi/SIP
- unzip sip into C:\sip-4.xx.x (example : C:\sip-4.15.3)
- Open up the Visual Studio 2010 Command Prompt
+ Start > All Programs > Microsoft Visual Studio 2010 > Visual Studio Tools > Visual Studio Command Prompt 2010
- Run the command to move to sip directory
+ cd C:\sip-4.xx.x (example cd C:\sip-4.15.3)
+ C:\Python27\python configure.py DEFINES+=QT_NAMESPACE=QT
Open C:\sip-4.xx.x\sipconfig.py and make sure DEFINES has been included QT_NAMESPACE
_default_macros = {
…........
'CXXFLAGS_WARN_OFF': '-W0',
'CXXFLAGS_WARN_ON': '-W3 -w34100 -w34189',
'DEFINES': 'UNICODE WIN32 QT_LARGEFILE_SUPPORT QT_NAMESPACE=QT',
'DEL_FILE': 'del',
…...........
}


Add there line before defiles.append(“QT_THREAD_SUPPORT”)

defines.append("QT_THREAD_SUPPORT")

defines.append("QT_NAMESPACE=QT")
# Handle library directories.
libdir_qt = self.optional_list("LIBDIR_QT")
libdir.extend(libdir_qt)
rpaths.extend(libdir_qt)

if qt_version >= 0x040000:

+ nmake
+ nmake install
Check if sip has been installed into Python27 directory:
C:\Python27\sip.exe
C:\Python27\Lib\site-packages\sipconfig.py
C:\Python27\Lib\site-packages\sip.pyd
C:\Python27\Lib\site-packages\sipdistutils.py
C:\Python27\Lib\site-packages\siputils.py

- Open python interpreter and check the modules by using:

from sip import *
print SIP_VERSION_STR

If it doesn't give any error messages about a DLL or something, it is installed correctly.

2. Compile PyQt4:
- Download PyQt4 4.10.3 Source
- Unzip the PyQt4 source to C:\PyQt-win-gpl-4.10.3
- Open Visual Studio 2010 Command Prompt
- Run the command below

set QTDIR=C:\Qt\4.8.5\
set PATH=%PATH%;C:\Qt\4.8.5\bin\
cd C:\PyQt-win-gpl-4.10.3
C:\Python27\python configure.py -w
Enter “yes” to the question
nmake
nmake install


If everything ok, you can check:

Open Python Interpreter

C:\>python
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt4
>>> from PyQt4 import QtCore
>>>


If not, check if your PyQt has beeen install correctly or you must manual copy from compile project to Python27 directory.
You need to add the folder that contains Qt DLLs to the environment path variables, by using the Control Panel -> System -> Advanced -> Environment Variables



3. Nullsoft installer to make installable binary package:
    - Download and install Nullsoft installers latest version
    - Right click C:\PyQt-win-gpl-4.10.3\PyQt.nsi and select "Compile NSIS Script"
    ( unfortunatelly the script gives a lot of errors, you need to copy/paste some files and create folders by your self according to the complains of the compiler )

Credit: computerline1z@gmail.com

Saturday, 15 February 2014

Xây dựng trình căm cho IDA Pro (Phần 1)

 

[Bản dịch dựa theo tài liệu của tác giả Steve Micallef steve@binarypool.com, xuất bản năm 2009]

1. Giới thiệu

1.1 Lý do của tài liệu này ?

Sau một khoản thời gian dài tìm hiểu các tập tin tiêu đề (header file) của IDA và nghiên cứu mã nguồn plugins của những người khác. Tôi nhận thấy cần thiết phải có một cách bắt đầu dễ dàng hơn cho những ai muốn viết trình cắm cho IDA. Mặc dù những ghi chú trong các tập tin tiêu đề cực kỳ chi tiết, Tôi cảm thấy một chút khó khăn khi tìm kiếm một số thứ qua nhiều việc thử và sai. Tôi nghĩ rằng tôi sẽ viết bài hướng dẫn này để thử nghiệm và giúp cho những người mới bắt đầu, và hi vọng tài liệu sẽ hữu ích để tra cứu một cách nhanh chóng cho những người phát triển trình cắm. Tôi cũng dành một phần để cài đặt môi trường mà sẽ giúp cho quy trình phát triển nhanh hơn.

1.2 Những điều được đề cập

Tài liệu này sẽ dẫn dắt bạn bắt đầu với việc phát triển các trình cắm (plugin) cho IDA, đầu tiên sẽ bắt đầu giới thiệu SDK, tiếp theo là cài đặt môi trường phát triển và xây dựng ứng dụng trên nhiều nền tảng. Bạn sẽ dần hiểu được một cách rõ ràng làm thế nào mà một số lượng lớn lớp và cấu trúc được dùng, tiếp theo là việc sử dụng một số hàm thông dụng. Cuối cùng, tôi sẽ trình bày một vài ví dụ về việc sử dụng những hàm API của IDA cho những việc cơ bản như việc lặp qua các hàm, để cấy vào trình debug và thao tác với cơ sở dữ liệu của IDA (tập tin IDB). Sau khi đọc xong tài liệu này, bạn có thể ứng dụng những kiến thức đã học được để xây dựng những trình cắm của bạn và hi vọng bạn sẽ chia sẻ nó cho cộng đồng người dùng IDA.

1.3 Những điều không được đề cập

Tôi tập trung vào hợp ngữ x86 bởi vì nó là nền tảng mà tôi có kinh nghiệm nhất, mặc dù hầu hết những gì được đề cập ở đây có thể được sử dụng cho bất cứ kiến trúc nào được hỗ trợ bởi IDA (trong thực tế là tất cả). Mặc dù vậy, nếu bạn muốn một tài liệu tham khảo toàn diện cho tất cả các hàm của IDA, tôi khuyên bạn nên xem qua các tập tin tiêu đề.

Tài liệu này tập trung chủ yếu vào các hàm “chỉ đọc” trong SDK, thay vì các hàm để thêm ghi chú, sửa lỗi, định nghĩa cấu trúc dữ liệu, và những thứ khác. Những phần đó chiếm phần lớn trong SDK, nhưng không được đề cập đến ở đây để giữ cho tài liệu này có kích thước cố định.

Tôi cũng bỏ qua cấu trúc netnode trong tài liệu này, cùng với nhiều cấu trúc, lớp bởi vì IDA SDK rất lớn, và bao gồm nhiều thứ được sử dụng cho những mục đích riêng – một bài viết không thể đề cập đến tất cả mọi thứ. Nếu có thứ gì đó mà bạn cảm thấy thật sự cần thiết phải được đề cập, hãy liên lạc với tôi và tôi sẽ có thể đưa nó vào phiên bản kế tiếp nếu nó không quá đặc biệt. Tôi cũng đã dự định sẽ viết một phần về đồ thị, nhưng tôi nhận ra là đã có một vài ví dụ trong SDK, và nó sẽ làm tràn kích cỡ của bài viết này. Sự lười biếng có thể cũng là một nhân tố tác động.

1.4 Những kiến thức cần thiết

Trước hết, bạn phải biết cách sử dụng IDA đến mức mà bạn có thể thoải mái khi duyệt qua mã nhị phân được dịch ngược (hợp ngữ) và sử dụng được trình gỡ rối. Bạn cần thiết phải được trang bị với một lượng kiến thức đầy đủ về ngôn ngữ C/C++ và hợp ngữ x86. Kiến thức về C++ quan trọng bởi vì SDK hầu hết được trình bày bằng C++. Nếu bạn không biết C++ nhưng biết C, bạn cần tìm hiểu những khái niệm tổng quát về phương pháp lập trình hướng đối tượng (OPP) như lớp, đối tượng, phương thức và kế thừa.

1.5 Yêu cầu về phần mềm

Để viết trình cắm cho IDA, bạn cần chương trình IDA Pro 5.4, và bộ công cụ phát triển IDA (SDK), bộ này có thể được tải về miễn phí từ trang chủ của hex-rays http://www.hex-rays.com ngoài ra, bạn sẽ cần một trình dịch C/C++ với những công cụ cần thiết (Visual Studio, GCC, Borland, vv).

Bởi vì đã qua một thời gian dài kể từ khi phiên bản cuối cùng của tài liệu này (xin lỗi vì điều đó!), phiên bản này sẽ tập trung vào phiên bản 5.4 của IDA SDK. Nó sẽ rất cồng kềnh nếu phải nhấn mạnh tất cả những thay đổi trong phiên bản IDA 4.8. SDK hầu như đã được đóng băng kể từ phiên bản 4.9, bởi với những phiên bản cũ có thể vẫn chạy được.

1.6 Những thay thế cho C/C++

Nếu C không phải là ngôn ngữ mà bạn sử dụng, hãy xem xét đến IDAPython, bộ thư viện này có tất cả những chức năng của C++ cùng với những chức năng của ngôn ngữ Python. Tham khảo https://code.google.com/p/idapython/ để biết thêm chi tiết. Cũng đã có một tài liệu về việc sử dụng IDAPython được viết bởi Ero Carrera tại http://........./, mặc dù nó có vẻ đã không được cập nhật kể từ năm 2006.

Cũng có một bài viết được viết vào năm 2005 về việc sử dụng VB6 và C# để viết trình cắm cho IDA – tham khảo nó ở đây: http://www.openrce.org/. Một phiên bản có kiểu trình bày giống như tài liệu php của phiên bản trước của tài liệu này đã được lưu trữ tại OpenRCE, có thể cho người dùng thêm ghi chú, mã ví dụ, vv vào mỗi hàm.

1.7 Về tài liệu này

Nếu bạn có bất cứ ghi chú hoặc ý kiến nào, hoặc nếu bạn phát hiện ra lỗi, vui lòng liên lạc với tôi, Steve Micallef, tại địa chỉ steve@binarypool.com. Nếu bạn thật sự cảm thấy mình đã học được điều gì hữu ích từ tài liệu này thì tôi thật sự được kích lệ nếu bạn viết cho tôi một lá thư, điều này làm cho công việc này đáng giá.

Đã bốn năm kể từ phiên bản cuối cùng của tài liệu này, bởi vậy tôi sẽ cố gắng để giữ cho tài liệu này được cập nhật mới nhất. Bạn sẽ luôn có thể lấy phiên bản mới nhất của tài liệu này tại http://www.binarypool.com/idapluginwriting/.

1.8 Lịch sử sửa đổi

  • Phiên bản 1.0 [7,2005]
    1. Xuất bản lần đầu tiên
  • Phiên bản 1.1 [5, 2009]
    1. Cập nhật phiên bản SDK mới nhất
    1. Một vài cập nhật mới và sửa đổi.
    1. Thay đổi những ví dụ từ Visio 2003 thành Visio 2008
    1. Một vài hàm mới được đề cập.
    1. Thêm vào một vài ví dụ.

1.9 Lời cảm ơn

Tôi xin gởi lời cảm ơn đến Ilfak Guilfanov và Hex-rays bởi việc họ tiếp tục hỗ trợ để tài liệu này đến được với mọi người và cho một sản phẩm tuyệt vời.

1.10 Đọc thêm

Kể từ phiên bản đầu tiên của tài liệu này, vẫn có nhiều giới hạn thông tin về việc xây dựng trình cắm cho IDA. Có hai nguồn tài nguyên tốt vẫn còn được hỗ trợ tại Hex-Rays là https://www.hex-rays.com/products/ida/support/index.shtml và IDA Place. Nếu bạn gặp khó khăn khi viết trình cắm, bạn luôn có thể hỏi để được trợ giúp trên diễn đàn hỗ trợ của Hex-Rays, nơi mà thậm chí nếu SDK không được hỗ trợ chính thức, thì một vài người trong Hex-Rays(hoặc một trong số nhiều người dùng IDA) sẽ sẵn sàng để giúp bạn.

Một nguồn tài nguyên tốt là http://www.openrce.org/, nơi bạn sẽ tìm thấy không chỉ một vài bài viết tuyệt vời về kỹ thuật đảo mã, mà còn tìm thấy công cụ, những trình cắm và tài liệu nữa. Ở đây có rất nhiều người say mê trong sân chơi này, những người này hầu hết sẽ sẵn sàng giúp bạn về bất cứ vấn đề nào liên quan đến IDA hoặc những vấn đề chung về đảo mã.

Kể từ phiên bản đầu tiên của tài liệu này, Chris Eagle cùng với No Starch Press đã cho xuất bản cuốn sách “The IDA Pro Book.” Đây là cuốn sách rất cần thiết cho những người dùng IDA và viết trình cắm. Nếu bạn muốn mua cuốn sách này từ Amazon, Vui lòng sử dụng liên kết này để xác nhận là bạn đến từ bài viết này (Tôi sẽ được nhận một phần trăm nhỏ từ giá sách, nhưng bạn sẽ không mất bất cứ khoản phí nào).

(Còn tiếp tục …)

Compiling PySide for IDA Pro 6.1 on Windows (Dịch PySide cho IDA Pro 6.1)


02/15/2014

https://www.facebook.com/luzxs

My prebuild for IDA: https://anonfiles.com/file/84b6ed79703b94e5e360aa06350fb651
Notes: Replace Qt*.dll from your IDA Dir with Qt*.dll in this settup, because it difference version

If you've ever wanted to use IDA's native GUIs, you'll need PySide. Unfortunately PySide is annoying to compile, and the only available binaries are for Python 2.6. This should work for any version.
Note: The python module installer executable at the end of this guide did not work for me. The compiled pyd and dll files, however were completely usable from within IDA.
Prequisites
·         Python 2.7
§  Run and install, I’ll be using C:\Python27
·         Perl 5.18
·         Visual Studio 2010
·         Visual Studio 2010 Service Pack 1
·         Windows SDK v7.0 is required when building against Python 2.6, 2.7 or 3.2
·         Qt 4.8.5 Source Code (Qt libraries 4.8.5 for Windows (VS 2010, 235 MB))
§  Run and install this in your computer, I’ll be using C:\Qt\4.8.5
·         After setup these tool, you need to add some key in the Environment Variables
o   Right Click Computer > Properties > Advanced > Environment Variables…
§  INCLUDE=C:\Program Files\Microsoft Visual Studio 10.0\VC\include;C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include;C:\Qt\4.8.5\include
§  LIB=C:\Python27\Lib;C:\Qt\4.8.5\lib
§  PYTHONHOME=C:\Python27
§  QMAKESPEC=win32-msvc2010
§  QTDIR=C:\Qt\4.8.5
§  QT_NAMESPACE=QT
§  PATH=%PATH%;%QTDIR%\bin;C:\Python27;C:\Python27\Scripts;C:\Qt\4.8.5\qmake

Compiling QT 4

It is necessary to build the Qt environment, because IDA is shipped with a custom version of Qt which wraps its classes inside the QT namespace (we’ll see later why that is so).
Download the latest version of jom from http://qt-project.org/wiki/jom It will accelerate the build process by using all available cores at build time, more on this further down. Extract jom files to
C:\Qt\jom
Start Visual Studio 2010 Command Prompt as an administrator.
On Win7 this can be done by right-clicking Start > Programs > Microsoft Visual Studio 2010 > Visual Studio Tools  > Visual Studio Command Prompt (2010) and choosing "Run as Administrator" from the popup menu.
On Win8 you can reach the shortcut by typing "Visual Studio" to get a list of app and shortcuts known to the system, it should list this particular shortcut to. Right-click it and choose to run as administrator from the bottom ribbon.
Run the following commands in it (every line is a different command. Type it, then press Enter):
>> cd c:\Qt\4.8.5
To compile both debug and release versions type or copy/paste:
C:\Qt\4.8.5>configure -debug-and-release -platform win32-msvc2010 -no-qt3support -qtnamespace QT
I chose to only compile the release version like so:
C:\Qt\4.8.5>configure -release -opensource -platform win32-msvc2010 –no-qt3support –qtnamespace QT
Note:
1.      Don't get irritated by the -platform flag reading "win32-msvc2010". It simply means that the MS Visual Studio compiler will be used and does not specify the architecture (x64 or x32, which was in fact already chosen by starting the Visual Studio x64 command prompt above). In other words:  "-platform" is always "win32-msvc2010" for us in the context of this example, even for win64 builds.
2.      If you customize the configure line, make sure you leave in the -qtnamespace QT! Otherwise your binaries will be unusable from within IDA.
This will take a few minutes, depending on your hardware. When it's done it should report back by printing:
"Qt is now configured for building. Just run nmake.To reconfigure, run nmake confclean and configure."
Build Qt using jom
Jom is an nmake replacement for Qt compilation on multi-core CPUs. Its parameter -j N allows to setup the number of parallel processes for compilation. Larger is better, where N is the number of CPU cores you want to utilize for Qt compilation. The number of physical CPU cores is a good choice for N, e.g. 4 on a typical quad-core CPU.
Usually compilation takes about 10 hours on a single core, with jom and an SSD drive it took only a bit more than 1 hour on my machine (Windows 8, 64bits)
Still in the same command prompt, enter and execute the following:
C:\Qt\4.8.5>..\jom\jom.exe -j 4
You might want to use a different number in the end if you have a system with more or less physical CPU cores.
This stage took around 2 hours on my PC
Example build may be fail, but it’s OK

Compiling PySide (We’ll use C:\ as Root Directory)

·         Get the packaging code
o   cd /d c:\
    • git clone git://gitorious.org/pyside/packaging.git
  • Change directory to packaging/setuptools/
o   cd /d c:\packaging\setuptools
·         Edit build.py to comment out the Tools repository
# Modules
modules = {
    'dev': [
        ["Apiextractor", "master", "https://github.com/PySide/Apiextractor.git"],
        ["Generatorrunner", "master", "https://github.com/PySide/Generatorrunner.git"],
        ["Shiboken", "master", "https://github.com/PySide/Shiboken.git"],
        ["PySide", "master", "https://github.com/PySide/PySide.git"],
        #["Tools", "master", "https://github.com/PySide/Tools.git"],
    ],
    'stable': [
        ["Apiextractor", "0.10.8", "https://github.com/PySide/Apiextractor.git"],
        ["Generatorrunner", "0.6.14", "https://github.com/PySide/Generatorrunner.git"],
        ["Shiboken", "1.0.9", "https://github.com/PySide/Shiboken.git"],
        ["PySide", "1.0.8", "https://github.com/PySide/PySide.git"],
        #["Tools", "0.2.13", "https://github.com/PySide/Tools.git"],
    ],
}

·         Open the Visual Studio 2010 Comand Prompt
·         Add the directory of qmake to your path
    • set path=%path%;C:\Qt\4.8.5\qmake
·         Change Directory to C:\packaging\setuptools\modules
o   cd /d c:\packaging\setuptools\modules
§  I use build.py –d to download all the repositories, but It get error, so I manual download package from it repo
§  In Command Prompts
·         git clone https://github.com/PySide/Apiextractor.git && git clone https://github.com/PySide/Generatorrunner.git && git clone https://github.com/PySide/Shiboken.git && git clone https://github.com/PySide/PySide.git
·         ! Notes : All command is in oneline and you must install gnuwin32 to this command to run, or you can type one command each line (ex: git clone https://github.com/PySide/Apiextractor.git)
·         Change directory into each of the repositories and run the following commands to checkout repo:
o   Apiextractor
§  cd /d \packaging\setuptools\modules\Apiextractor
§  git checkout 0.10.8
o   Generatorrunner
§  cd /d \packaging\setuptools\modules\Generatorrunner
§  git checkout 0.6.14
o   Shiboken
§  cd /d \packaging\setuptools\modules\Shiboken
§  git checkout 1.0.9
o   PySide
§  cd /d \packaging\setuptools\modules\PySide
§  git checkout 1.0.8
·         Download this patch and apply it using git
o   Copy pyside.diff to C:\packaging\setuptools\
§  cd /d  c:\packaging\setuptools
§  git apply --ignore-whitespace pyside.diff
Notes : If this task fail, you can manual apply to source by open pyside.diff and read instruction
+++ : File need to edit
@@ 8, 9 … Line to edit
-       delete line
+ add line
  • Patch the calls to deallocData in Siboken so they pass in two arguments (second argument should be True)
    • c:\packaging\setuptools\modules\Shiboken\libshiboken\basewrapper.cpp
extern "C"  {
void deallocData(SbkObject* self, bool cleanup);
static void SbkObjectTypeDealloc(PyObject* pyObj);

void DtorCallerVisitor::done() {
Shiboken::Object::deallocData(m_pyObj, true);
 std::list<std::pair<void*, SbkObjectType*> >::const_iterator it = m_ptrs.begin();
c:\packaging\setuptools\modules\Shiboken\libshiboken\basewrapper_p.h
* Destroy internal data
**/
void deallocData(SbkObject* self);
void deallocData(SbkObject* self, bool cleanup);
} // namespace Objectging
c:\packaging\setuptools\modules\Shiboken\CmakeLists.txt
set(shiboken_VERSION "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}.${shiboken_MICRO_VERSION}")
IF (NOT $ENV{QT_NAMESPACE} STREQUAL "")
  add_definitions(-DQT_NAMESPACE=$ENV{QT_NAMESPACE})
ENDIF (NOT $ENV{QT_NAMESPACE} STREQUAL "")
option(BUILD_TESTS "Build tests." TRUE)
C:\packaging\setuptools\modules\shiboken\generator\cppgenerator.cpp
Bug : error C2661: 'QFileWrapper::open' : no overloaded function takes 3 arguments http://comments.gmane.org/gmane.comp.lib.qt.pyside/2995
With QT > 4.8.0
Locate :
--------
&& (func->name() != "qt_metacall"))
  overloads.append(func);
---------
and replace with:
……………
&& (func->name() != "qt_metacall")) {
                    if (func->toString().contains("open")) {
                        if (func->isVirtual())
                            overloads.append(func);
                    }
                    else
                        overloads.append(func);
                }
………….
·         
      Open up another Visual Studio 2010 Command Prompt
·         Add cmake/qmake/git/qt to your PATH and set the Qt namespace
·         set path=%path%;C:\CMake 2.8\bin
·         set path=%path%;C:\Qt\4.8.5\qmake
·         set path=%path%;C:\Git\bin
·         set path=%path%;C:\Qt\4.8.5\bin
·         set QT_NAMESPACE=QT
·         Start the build process
o    Build.py
o    This takes around an hour on my PC

Notes :
If you get error while linking with generatorrunner.exe, please copy QtCore4.dll, QtGui4.dll, QtXml4.dll from C:\Qt\4.8.5\bin to C:\packaging\setuptools\install-py2.7-qt4.8.5\bin, this error cause by generatorrunner.exe can’t get it dependency library.

·         Your new PySide installer should be available in packaging\setuptools\dist

Thursday, 8 November 2007

Xây dựng trình cắm cho IDA Pro - Phần 25

.4 Đặt và lưu điểm dừng hàng loạt
//
// bulkbpt.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <diskio.hpp>
#include <dbg.hpp>

// Maximum number of breakpoints that can be set
#define MAX_BPT 100

// Insert the following two lines into your plugins.cfg file
// Replace pluginname with the filename of your plugin minus
// the extension
//
// Write_Breakpoints pluginname Alt-D 0
// Read_Breakpoints pluginname Alt-E 1
//

void read_breakpoints() {
char c, ea[9];
int x = 0, b = 0;
ea_t ea_list[MAX_BPT];
// Ask the user for the file containing the breakpoints
char *file = askfile_cv(0, "", "Breakpoint list file...", NULL);
// Open the file in read-only mode
FILE *fp = fopenRT(file);
if (fp == NULL) {
warning("Unable to open breakpoint list file, %s\n", file);
return;
}
// Grab 8-byte chunks from the file
while ((c = qfgetc(fp)) != EOF && b < MAX_BPT) {
if (isalnum(c)) {
ea[x++] = c;
if (x == 8) {
// NULL terminate the string
ea[x] = 0;
x = 0;
// Convert the 8 character string to an address
str2ea(ea, &ea_list[b], 0);
msg("Adding breakpoint at %a\n", ea_list[b]);
// Add the breakpoint as a software breakpoint
add_bpt(ea_list[b], 0, BPT_SOFT);
b++;
}
}
}
// Close the file handle
qfclose(fp);
}

void write_breakpoints() {
char c, ea[9];
int x = 0, b = 0;
ea_t ea_list[MAX_BPT];
// Ask the user for the file to save the breakpoints to
char *file = askstr(0, "", "Breakpoint list file...", NULL);
// Open the file in write-only mode
FILE *fp = ecreateT(file);
for (int i = 0; i < get_bpt_qty(); i++) {
bpt_t bpt;
char buf[MAXSTR];

getn_bpt(i, &bpt);
qsnprintf(buf, sizeof(buf)-1, "%08a\n", bpt.ea);
ewrite(fp, buf, strlen(buf));
}
// Close the file handle
eclose(fp);
}

void IDAP_run(int arg)
{
// Depending on the argument supplied,
// read the breakpoint list from a file and
// apply it, or write the current breakpoints
// to a file.
switch (arg) {
case 0:
write_breakpoints();
break;
case 1:
default:
read_breakpoints();
break;
}
}

int IDAP_init(void)
{
return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

// These are irrelevant because they will be overridden by
// plugins.cfg.
char IDAP_comment[] = "Bulk Breakpoint Setter and Recorder";
char IDAP_help[] =
"Sets breakpoints at a list of addresses in a text file"
" or saves the current breakpoints to file.\n"
"The read list must have one address per line.\n";


char IDAP_name[] = "Bulk Breakpoint Setter and Recorder";
char IDAP_hotkey[] = "Alt-B";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};