LazyIDA是一款IDA插件,项目地址GitHub - L4ys/LazyIDA: Make your IDA Lazy!
外部引用
from __future__ import division
from __future__ import print_function
from struct import unpack
import idaapi
import idautils
import idc
from PyQt5.Qt import QApplication
from __future__ import division
: 这行代码是用于确保Python 2和Python 3之间的兼容性。在Python 2中,除法运算默认是整数除法,而在Python 3中,除法运算默认是浮点数除法。通过这行代码,你可以确保在Python 2中使用浮点数除法。
from __future__ import print_function
: 这行代码是为了确保在Python 2中使用print
作为函数而不是语句。在Python 3中,print
是一个函数,而在Python 2中,它是一个语句。这行代码是为了让Python 2的print
行为更接近于Python 3
from struct import unpack
: struct
模块用于在Python中处理C结构。unpack
函数用于将打包的二进制数据解包为Python数据类型。
import idaapi
: 这行代码导入了IDA Pro的API,允许你使用IDA Pro的功能和插件。
import idautils
: idautils
模块包含了一些实用的工具函数,用于处理和操作IDA Pro中的数据。
import idc
: idc
是IDA Pro的核心模块,提供了与IDA Pro数据库交互的功能
from PyQt5.Qt import QApplication
:这行代码从PyQt5的Qt模块导入了QApplication
类。PyQt5是一个用于创建图形用户界面(GUI)的Python库,而QApplication
类是所有PyQt5 GUI应用程序的入口点。
全局变量和函数
这部分定义了一些元组和字符串,之后要说的重点是u16,u32和u64这三个函数
ACTION_CONVERT = ["lazyida:convert%d" % i for i in range(10)]
ACTION_SCANVUL = "lazyida:scanvul"
ACTION_COPYEA = "lazyida:copyea"
ACTION_GOTOCLIP = "lazyida:gotoclip"
ACTION_XORDATA = "lazyida:xordata"
ACTION_FILLNOP = "lazyida:fillnop"
ACTION_HX_REMOVERETTYPE = "lazyida:hx_removerettype"
ACTION_HX_COPYEA = "lazyida:hx_copyea"
ACTION_HX_COPYNAME = "lazyida:hx_copyname"
ACTION_HX_GOTOCLIP = "lazyida:hx_gotoclip"
u16 = lambda x: unpack("<H", x)[0]
u32 = lambda x: unpack("<I", x)[0]
u64 = lambda x: unpack("<Q", x)[0]
ARCH = 0
BITS = 0
u16,u32,u64函数
这三个函数涉及的库函数解读和lambda表达式在下文,还有一个demo,这里概述一下三个函数的作用
这三个函数都接受一个x作为参数
然后调用unpack函数将pack函数打包成的bytes对象解包
<表示的是小端序,H表示的是两个字节,16位
I表示的是四个字节,32位
Q表示的八个字节,64位
lambda表达式
例如u16
lambda表达式,定义了一个函数u16
lambda x:表示接受的变量是x
函数的操作是unpack("<H", x)[0]
unpack函数
在上文from struct import unpack中导入了unpack
官网解释
库
struct — Interpret bytes as packed binary data — Python 3.12.1 documentation
This module converts between Python values and C structs represented as Python bytes objects.
这个库是用字节码实现在Python的值和C的结构体之间的转换
unpack
struct.unpack(format, buffer)
这个函数用于解包由 pack
函数打包过的 buffer。其中,format 是打包时使用的格式字符串(Format string),buffer 是打包后的字节串。
calcsize
struct.calcsize
返回与格式字符串 format
对应的结构体(以及由 pack(format,…)生成的 bytes 对象)的大小。
Format string
格式字符串描述了在打包和解包数据时的数据布局。它们由格式字符构建,这些格式字符指定了正在打包/解包的数据类型。此外,特殊字符还控制字节顺序、大小和对齐方式。每个格式字符串由一个可选的前缀字符组成,该字符描述数据的整体属性,以及一个或多个格式字符,这些字符描述实际的数据值和填充。
格式字符串的第一个字符可用于指示打包数据的字节顺序、大小和对齐方式
Native byte order取决于host system
标准大小仅取决于格式字符;请参阅“格式字符”部分中的表格
demo
from struct import *
print(pack("<i", 1))
print(pack(">i", 1))
'''
运行结果
b'\x01\x00\x00\x00'
b'\x00\x00\x00\x01'
'''
函数和类
copy_to_clip
def copy_to_clip(data):
QApplication.clipboard().setText(data)
设置剪贴板内容
clip_text
def clip_text():
return QApplication.clipboard().text()
返回剪贴板的内容
parse_location
def parse_location(loc):
try:
loc = int(loc, 16)
except ValueError:
try:
loc = idc.get_name_ea_simple(loc.encode().strip())
except:
return idaapi.BADADDR
return loc
try中将输入的数字转换成16进制
否则就用idc.get_name_ea_simple获取函数名对应的地址
如果都不是就返回BADADDR异常
hotkey_action_handler_t
这个类用于处理IDA pro中的动作
ida_kernwin API documentation
class hotkey_action_handler_t(idaapi.action_handler_t):
"""
Action handler for hotkey actions
"""
def __init__(self, action):
idaapi.action_handler_t.__init__(self)
self.action = action
def activate(self, ctx):
if self.action == ACTION_COPYEA:
ea = idc.get_screen_ea()
if ea != idaapi.BADADDR:
copy_to_clip("0x%X" % ea)
print("Address 0x%X has been copied to clipboard" % ea)
elif self.action == ACTION_GOTOCLIP:
loc = parse_location(clip_text())
if loc != idaapi.BADADDR:
print("Goto location 0x%x" % loc)
idc.jumpto(loc)
return 1
可以看到 hotkey_action_handler_t这个类继承了 action_handler_t类,并重写了activate这个函数
action_handler_t类
def activate(self, ctx)
激活一个动作。这个函数实现了动作的内核行为。当动作被触发时,它会被调用,无论是从菜单、弹出菜单、工具栏还是通过程序。
返回:非零值:所有IDA窗口将刷新。