首页 > 其他分享 >[IDA PRO] RVA 插件

[IDA PRO] RVA 插件

时间:2024-06-10 17:12:02浏览次数:17  
标签:插件 return PRO RVA idaapi offset action self def

IDA 插件 - 跳转到偏移量
IDA 插件 - 获取偏移量

Shift+G 跳转到指定RVA
Ctrl+Shift+C (或右键选择) 复制当前RVA到剪贴板

#------------------------------------------------------------------------------
# IDA Plugin to jump to an offset from the Imagebase.
# Copy the 'cvutils-getoffset.py' into the plugins directory of IDA
#------------------------------------------------------------------------------

VERSION = '1.1.0'
__AUTHOR__ = 'cra0'


PLUGIN_HOTKEY = "Shift+G"
PLUGIN_NAME = "Go To Offset("+PLUGIN_HOTKEY+")"
COPY_PLUGIN_HOTKEY = "Ctrl+Shift+C"


  
import os
import sys
import idc
import idaapi
import idautils
import string


major, minor = map(int, idaapi.get_kernel_version().split("."))
using_ida7api = (major > 6)
using_pyqt5 = using_ida7api or (major == 6 and minor >= 9)

idaver_74newer = (major == 7 and minor >= 4)
idaver_8newer = (major >= 8)

if idaver_74newer or idaver_8newer:
    newer_version_compatible = True
else:
    newer_version_compatible = False

if newer_version_compatible:
    #IDA 7.4+
    #https://hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml
    import ida_ida
    import ida_kernwin
    
if using_pyqt5:
    import PyQt5.QtGui as QtGui
    import PyQt5.QtCore as QtCore
    import PyQt5.QtWidgets as QtWidgets
    from PyQt5.Qt import QApplication

else:
    import PySide.QtGui as QtGui
    import PySide.QtCore as QtCore
    QtWidgets = QtGui
    QtCore.pyqtSignal = QtCore.Signal
    QtCore.pyqtSlot = QtCore.Slot
    from PySide.QtGui import QApplication
    


def PLUGIN_ENTRY():
    """
    Required plugin entry point for IDAPython Plugins.
    """
    return cvutils_offset()

class cvutils_offset(idaapi.plugin_t):

    flags = idaapi.PLUGIN_PROC #| idaapi.PLUGIN_HIDE
    comment = "Go to an offset."
    help = "Use the shortcut key to open the goto dialog box."
    wanted_name = PLUGIN_NAME
    # wanted_hotkey = PLUGIN_HOTKEY
    wanted_hotkey=''

    #--------------------------------------------------------------------------
    # Plugin Overloads
    #--------------------------------------------------------------------------

    def init(self):
        """
        This is called by IDA when it is loading the plugin.
        """

        # initialize the menu actions our plugin will inject
        self._init_action_goto_offset()

# GET OFFSET
        # initialize the menu actions our plugin will inject
        self._init_action_get_offset()
        # initialize plugin hooks
        self._init_hooks()
        # done
        idaapi.msg("%s %s initialized...\n" % (self.wanted_name, VERSION))
        return idaapi.PLUGIN_KEEP

    def run(self, arg):
        """
        This is called by IDA when this file is loaded as a script.
        """
        idaapi.msg("%s cannot be run as a script.\n" % self.wanted_name)

    def term(self):
        """
        This is called by IDA when it is unloading the plugin.
        """


        # unregister our actions & free their resources
        self._del_action_goto_offset()

# GET OFFSET
        # unhook our plugin hooks
        self._hooks.unhook()
        # unregister our actions & free their resources
        self._del_action_get_offset()

        # done
        idaapi.msg("%s terminated...\n" % self.wanted_name)

#  cvutils_getoffset
    #--------------------------------------------------------------------------
    # IDA Actions
    #--------------------------------------------------------------------------

    ACTION_GOTO_OFFSET  = "prefix:goto_offset"


    def _init_action_goto_offset(self):
        """
        Register the copy bytes action with IDA.
        """   
        vaction_desc = "Go to offset."
        if (sys.version_info > (3, 0)):
            # Describe the action using python3 copy
            action_desc = idaapi.action_desc_t(
                self.ACTION_GOTO_OFFSET,                                     # The action name.
                "Go to offset("+PLUGIN_HOTKEY+')',                                             # The action text.
                IDACtxEntry(goto_offset),                                # The action handler.
                PLUGIN_HOTKEY,                                              # Optional: action shortcut
                vaction_desc,                                               # Optional: tooltip
                31                                                          # Copy icon
            )
        else:
            # Describe the action using python2 copy
            action_desc = idaapi.action_desc_t(
                self.ACTION_GOTO_OFFSET,                                 # The action name.
                "Go to offset",                                         # The action text.
                IDACtxEntry(goto_offset),                            # The action handler.
                PLUGIN_HOTKEY,                                          # Optional: action shortcut
                vaction_desc,                                           # Optional: tooltip
                31                                                      # Copy icon
            )


        # register the action with IDA
        assert idaapi.register_action(action_desc), "Action registration failed"


    def _del_action_goto_offset(self):
        """
        Delete the bulk prefix action from IDA.
        """
        idaapi.unregister_action(self.ACTION_GOTO_OFFSET)
    #--------------------------------------------------------------------------
    # Plugin Hooks
    #--------------------------------------------------------------------------

    def _init_hooks(self):
        """
        Install plugin hooks into IDA.
        """
        self._hooks = Hooks()
        self._hooks.ready_to_run = self._init_hexrays_hooks
        self._hooks.hook()

    def _init_hexrays_hooks(self):
        """
        Install Hex-Rrays hooks (when available).
        NOTE: This is called when the ui_ready_to_run event fires.
        """
        if idaapi.init_hexrays_plugin():
            idaapi.install_hexrays_callback(self._hooks.hxe_callback)

    #--------------------------------------------------------------------------
    # IDA Actions
    #--------------------------------------------------------------------------

    ACTION_GET_OFFSET  = "prefix:get_offset"


    def _init_action_get_offset(self):
        """
        Register the get offset action with IDA.
        """   
        # If the action is already registered, unregister it first.
        if idaapi.unregister_action(self.ACTION_GET_OFFSET):
            idaapi.msg("Warning: action was already registered, unregistering it first\n")
        
        vaction_desc = "Get the offset from the image base of the current cursor address."
        if (sys.version_info > (3, 0)):
            # Describe the action using python3 copy
            action_desc = idaapi.action_desc_t(
                self.ACTION_GET_OFFSET,                                     # The action name.
                "Get Offset("+COPY_PLUGIN_HOTKEY+')',                                               # The action text.
                IDACtxEntry(getcopy_offset),                                # The action handler.
                COPY_PLUGIN_HOTKEY,                                              # Optional: action shortcut
                vaction_desc,                                               # Optional: tooltip
                31                                                          # Copy icon
            )
        else:
            # Describe the action using python2 copy
            action_desc = idaapi.action_desc_t(
                self.ACTION_GET_OFFSET,                                 # The action name.
                "Get Offset("+COPY_PLUGIN_HOTKEY+')',                                           # The action text.
                IDACtxEntry(getcopy_offset),                            # The action handler.
                COPY_PLUGIN_HOTKEY,                                          # Optional: action shortcut
                vaction_desc,                                           # Optional: tooltip
                31                                                      # Copy icon
            )

        # register the action with IDA
        assert idaapi.register_action(action_desc), "Action registration failed"


    def _del_action_get_offset(self):
        """
        Delete the bulk prefix action from IDA.
        """
        idaapi.unregister_action(self.ACTION_GET_OFFSET)
#------------------------------------------------------------------------------
# Display a warning message box
#------------------------------------------------------------------------------
def display_warning(message): 
    if newer_version_compatible:
        return idaapi.warning(message)
    else:
        return idc.Warning(message)
   
#------------------------------------------------------------------------------
# Jump to a certain address
#------------------------------------------------------------------------------
def jump_to_address(jump_address): 
    if newer_version_compatible:
        ida_kernwin.jumpto(jump_address)
    else:
        idc.Jump(jump_address)


#------------------------------------------------------------------------------
# Image Min EA
#------------------------------------------------------------------------------
def get_minEA(): 
    if newer_version_compatible:
        return ida_ida.inf_get_min_ea()
    else:
        return idc.MinEA()

#------------------------------------------------------------------------------
# IsBadAddress
#------------------------------------------------------------------------------

def is_hex(s):
     hex_digits = set(string.hexdigits)
     # if s is long, then it is faster to check against a set
     return all(c in hex_digits for c in s)

def is_hex(s):
    try:
        int(s, 16)
        return True
    except ValueError:
        return False

def isvalid_address(ea):
    """Check if the given address is valid
    
    Arguments:
        ea: The linear address to check.
    """   
    if (ea == idaapi.BADADDR):
        print("[%x] BADADDR" % ea)
        return 0
        
    pe_min_ea = get_minEA()
       
    if (ea < pe_min_ea):
        print("[%x] is lower than MinEA [%x]" % (ea, pe_min_ea))
        return 0
               
    if not idaapi.getseg(ea):
        print("[%x] getseg failed" % ea)
        return 0
    
    return 1


#------------------------------------------------------------------------------
# Go to offset
#------------------------------------------------------------------------------

def goto_offset():
    hint_min_offset = get_minEA() - idaapi.get_imagebase()
    # print('hint_min_offset:',hint_min_offset)
    #Use string for now, force them to use hex as the offset
    offset_value=None
    if newer_version_compatible:
        offset_value = ida_kernwin.ask_str("0x%x" % hint_min_offset, 0, "To Offset[HEX]:")    
    else:
        offset_value = idc.AskStr("0x%x" % hint_min_offset, "To Offset[HEX]:")

    if not offset_value:
        print("No value was provided. Ignoring")
        return
    
    if not is_hex(offset_value):
        print("Bad input; It doesn't contain valid hex")
        display_warning("Bad Input!")
        return
        
    offset_hex = int(offset_value, 16)
    if offset_hex == 0:
        display_warning("Input is Invalid!")
        return
       
    image_base = idaapi.get_imagebase()
    jump_address = image_base + offset_hex
    
    if (isvalid_address(jump_address)):
        print ("Offset [%x] =-> Address [0x%x]" % (offset_hex, jump_address))
        jump_to_address(jump_address)
    else:
        display_warning("Bad Offset!")
    
    return

#------------------------------------------------------------------------------
# IDA ctxt
#------------------------------------------------------------------------------

class IDACtxEntry(idaapi.action_handler_t):

    def __init__(self, action_function):
        idaapi.action_handler_t.__init__(self)
        self.action_function = action_function

    def activate(self, ctx):
        self.action_function()
        return 1

    def update(self, ctx):
        return idaapi.AST_ENABLE_ALWAYS

#------------------------------------------------------------------------------
# Plugin Hooks
#------------------------------------------------------------------------------

class Hooks(idaapi.UI_Hooks):

    def __init__(self):
        # Call the __init__ method of the superclass
        super(Hooks, self).__init__()

        # Get the IDA version
        major, minor = map(int, idaapi.get_kernel_version().split("."))
        self.newer_version_compatible = (major == 7 and minor >= 4) or (major >= 8)
        
        # If the IDA version is less than 7.4, define finish_populating_tform_popup
        if not self.newer_version_compatible:
            self.finish_populating_tform_popup = self._finish_populating_tform_popup

    def finish_populating_widget_popup(self, widget, popup_handle, ctx=None):
        """
        A right click menu is about to be shown. (IDA 7.x)
        """
        inject_address_offset_copy_actions(widget, popup_handle, idaapi.get_widget_type(widget))
        return 0


    def _finish_populating_tform_popup(self, form, popup):
        """
        A right click menu is about to be shown. (IDA 6.x)
        """
        inject_address_offset_copy_actions(form, popup, idaapi.get_tform_type(form))
        return 0

    def hxe_callback(self, event, *args):
        """
        HexRays event callback.
        """

        #
        # if the event callback indicates that this is a popup menu event
        # (in the hexrays window), we may want to install our prefix menu
        # actions depending on what the cursor right clicked.
        #

        if event == idaapi.hxe_populating_popup:
            form, popup, vu = args

            idaapi.attach_action_to_popup(
                form,
                popup,
                cvutils_offset.ACTION_GET_OFFSET,
                "Get Address Offset",
                idaapi.SETMENU_APP,
            )

        # done
        return 0

#------------------------------------------------------------------------------
# Prefix Wrappers
#------------------------------------------------------------------------------

def inject_address_offset_copy_actions(widget, popup_handle, widget_type):
    if widget_type == idaapi.BWN_DISASMS:
        idaapi.attach_action_to_popup(
            widget,
            popup_handle,
            cvutils_offset.ACTION_GET_OFFSET,
            "Get Address Offset",
            idaapi.SETMENU_APP
        )
    return 0

#------------------------------------------------------------------------------
# Get Screen linear address
#------------------------------------------------------------------------------
def get_screen_linear_address(): 
    if newer_version_compatible:
        return idc.get_screen_ea()
    else:
        return idc.ScreenEA()


#------------------------------------------------------------------------------
# Get Offset
#------------------------------------------------------------------------------
def setClipboardText(data):
    cb = QApplication.clipboard()
    cb.clear(mode=cb.Clipboard )
    cb.setText(data, mode=cb.Clipboard)

def getcopy_offset():
    """
    Gets the offset of the current cursor's address
    """
    vImagebase = idaapi.get_imagebase()
    vCurrentPos = get_screen_linear_address()
    if vCurrentPos != idaapi.BADADDR:
        vOffset = vCurrentPos - vImagebase
        print ("Address [0x%x] =-> Offset [%x] Copied to Clipboard!" % (vCurrentPos, vOffset))
        setClipboardText("%x" % vOffset)
    return

标签:插件,return,PRO,RVA,idaapi,offset,action,self,def
From: https://www.cnblogs.com/DirWang/p/18237511

相关文章

  • mORMot and Open Source friends SynProject Tutorial (SynProject教程)
    mORMotandOpenSourcefriendsSynProjectTutorial--(SynProject教程)第一步本页介绍SynProject的一些典型用法。我们将为mORMot框架本身创建一个源代码存储库和相关的文档。您要求文档,我们将通过SynProject自动生成它!我们需要什么因此,我们在硬盘上的D:\Dev\Lib文件夹中......
  • JavaScript prototype(原型对象)
     所有的JavaScript对象都会从一个prototype(原型对象)中继承属性和方法。在前面的章节中我们学会了如何使用对象的构造器(constructor):实例functionPerson(first,last,age,eyecolor){this.firstName=first;this.lastName=last;this.age=age;this.eye......
  • Windows11系统WmsProxyStub.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个WmsProxyStub.dll文件(挑选合适的版本文件)......
  • [AI Google] 使用 Gemini 取得更多成就:试用 1.5 Pro 和更多智能功能
    总结Google正在为超过35种语言的GeminiAdvanced订阅者推出Gemini1.5Pro。此次更新包括100万个token的上下文窗口、改进的数据分析功能和增强的多模态图像理解。新功能包括用于自然对话的GeminiLive、先进的规划工具和可定制的Gems。更新还集成了更多Googl......
  • 二、插件
    推荐网站:https://vimjc.com大部分插件的介绍和大概设置方法都在这里。一、安装neovim完全体Ubuntu自带的vim在编译时会缺少部分组件,建议从ppa安装完全体的neovim以进行后续的设置。#使用最新版Neovimsudoadd-apt-repositoryppa:neovim-ppa/stable#配套环境p......
  • 网上 copy 的一段 javascript 代码 String.prototype.replaceAll = fucntion(){...}
    早些年,浏览器没有内置字符串的replaceAll()方法,就从网上copy了一段replaceAll()的实现:String.prototype.replaceAll=function(AFindText,ARepText){raRegExp=newRegExp(AFindText,"g");returnthis.replace(raRegExp,ARepText)}今天突然遇到一个问题,定位到了这段代码,我......
  • Prov-GigaPath:新型数字病理基础模型|顶刊精析·2024-06-10
    小罗碎碎念顶刊精析|2024-06-10首先祝各位老师、师兄师姐、师弟师妹们端午节快乐!!小罗是社恐,所以就不一一发消息问候了,哈哈。今天这篇推文是昨天下午写完的,想着时间有点晚了,所以就放到今天发了。这篇文献想必很多研究病理组学的老师已经看到了,朋友圈也看到了这篇文献相......
  • Git-SSL证书-验证问题-可能由加速器引起:SSL certificate problem: unable to get loca
    一、问题的出现    当我们在使用Git 将本地仓库的代码推送到远程仓库或者从远程仓库克隆到本地时可能遇到以下问题。fatal:unabletoaccess'https://github.com/User/XXX/':SSLcertificateproblem:unabletogetlocalissuercertificate    即......
  • ChatGPT Prompt技术全攻略-总结篇:Prompt工程技术的未来发展
    系列篇章......
  • VSCode超过390万下载的请求插件
    ThunderClient是一款在VSCode(VisualStudioCode)中非常受欢迎的RESTAPI客户端插件,由RangaVadhineni开发,现在已经有超过390万的下载量。它允许开发者直接在编辑器内发送HTTP请求,查看响应。ThunderClient提供了一个直观的界面来构建和测试API,非常适合前后端开发人......