Study/IDA

IDA 간단한 팝업창 만들기

대장흰둥 2021. 3. 22. 12:32
  • 액션은 처음에 먼저 등록이 되어야 한다 한 번 등록한 액션은 계속 사용할 수 있다
  • 등록된 액션은 메뉴, 툴바, 팝업창 등에 연결시킬 수 있다
  • 액션은 핸들러를 가지고 있는 데 activate, update 의 두 가지 콜백 함수를 가진다. 

Activate 는 액션이 실행될 때 호출되며, update 는 현재 액션이 사용 가능한지 아닌지를 알려 줄 수 있게 해 준다 

 

1. 액션 만들기

idaapi.action_desc_t(고유이름, 설명, 핸들러, 단축키, 메뉴와툴바의툴팁, 아이콘)

load_custom_icon() 으로 사용자 지정 아이콘을 등록할 수 있다.

 

ACTION_TEST = "testplugin:actiontest"

class PopupActionHandler(idaapi.action_handler_t):
    def __init__(self, action):
        idaapi.action_handler_t.__init__(self)
        self.action = action


def activate(self, ctx):
        if self.action == ACTION_TEST:
            print("TEST ACTION!") 
        else: 
            return 0

        return 1


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

PopupActionHandler 라는 이름으로 Handler class 를 생성해 주고, activate 로 나의 action이 ACTION_TEST testplugin:actiontest 이면 TEST ACTION을 출력해 준다

 

2. 액션 등록과 연결하기

 

# 편한 코딩을 위해 action들의 튜플을 만들어 둔다
actions=(
idaapi.action_desc_t(ACTION_TEST,"TESTPOPUPMENU!!!", PopupActionHandler(ACTION_TEST), None, None, 38), 
        )

        for i in actions:
            idaapi.register_action(i) 
            self.reg_actions.append(i.name) 
# 액션을 등록한다.

우선 idaapi.action_desc_t(액션 고유 이름, 액션 설명, 액션 핸들러 함수, 단축키, 메뉴와 툴바의 툴 팁, 아이콘) 의 순서로 action 들의 튜플을 만들어주고 

idaapi.register_action(액션)으로 액션을 등록한다. 

 

3. 우클릭 팝업메뉴에 액션 연결

 

class UIHook(idaapi.UI_Hooks):
    def __init__(self):
        idaapi.UI_Hooks.__init__(self) 

    # 팝업창 뜰때
    def finish_populating_tform_popup(self, form, popup):
        formtype = idaapi.get_tform_type(form) # 현재 창 정보를 가져와서

        if formtype == idaapi.BWN_DISASM or idaapi.BWN_DUMP:
            # 팝업에 내 action 추가
            idaapi.attach_action_to_popup(form, popup, ACTION_TEST, None)

 

우클릭 팝업 메뉴에 액션을 연결 하기 위해서 Hook을 만들고 연결시켜 준다 

if idaapi.get_tform_type(form) == idaapi.BWN_FUNCS:
                idaapi.attach_action_to_popup(form, popup, "my:action", "Others/")

다음과 같이 사용할 수도 있는데 BWN_FUNCS는 함수 창을 가리킨다. 함수 창에서 팝업을 열면 Others 안에 액션이 연결된다.

 

+ 다른곳에 액션 연결하기

 

메뉴에 액션 연결

idaapi.attach_action_to_menu(
    		'Edit/Other/Manual instruction...', # 메뉴 위치
    		'my:action',                    	# 고유이름
    		idaapi.SETMENU_APP)             	# 메뉴 추가 속성

 

툴바에 액션 연결

idaapi.attach_action_to_toolbar(
    		"AnalysisToolBar",  # 툴바이름
    		'my:action')    	# 고유이름

 

4. 가장 기본적인 플러그인 예시

 

import idaapi

class myplugin_t(idaapi.plugin_t):
    flags = idaapi.PLUGIN_UNL
    comment = "This is a comment"

    help = "This is help"
    wanted_name = "My Python plugin"
    wanted_hotkey = "Alt-F8"

    def init(self):
        idaapi.msg("init() called!\n")
        return idaapi.PLUGIN_OK

    def run(self, arg):
        idaapi.msg("run() called with %d!\n" % arg)

    def term(self):
        idaapi.msg("term() called!\n")

def PLUGIN_ENTRY():
    return myplugin_t()

#-*- coding: utf-8 -*-

from __future__ import print_function
import idaapi


ACTION_TEST = "testplugin:actiontest"


class UIHook(idaapi.UI_Hooks):
    def __init__(self):
        idaapi.UI_Hooks.__init__(self)

    # 팝업창 뜰때
    def finish_populating_tform_popup(self, form, popup):
        formtype = idaapi.get_tform_type(form) # 현재 창 정보를 가져와서

        if formtype == idaapi.BWN_DISASM or idaapi.BWN_DUMP:
            # 팝업에 내 action 추가
            idaapi.attach_action_to_popup(form, popup, ACTION_TEST, None)


class PopupActionHandler(idaapi.action_handler_t):
    def __init__(self, action):
        idaapi.action_handler_t.__init__(self)
        self.action = action


    # action이 실행될 때
    def activate(self, ctx):
        if self.action == ACTION_TEST:
            print("TEST ACTION!") 
        else:
            return 0

        return 1


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

    

class mytestplugin(idaapi.plugin_t):
    flags = idaapi.PLUGIN_HIDE
    comment = "This is Comment!"

    help = ""
    wanted_name = "TEST PLUGIN!!!"
    wanted_hotkey = ""

    def init(self):
        self.hexrays_inited = False
        self.reg_actions = [] # 등록된 actions 들을 담는 리스트
      
      
        arch = idaapi.ph_get_id()
        print(arch)
        inf = idaapi.get_inf_structure()

        if inf.is_64bit():
            print("64 Bit!")
        elif inf.is_32bit():
            print("32 Bit!")
        else:
            print("16 Bit!")
         
        print("TESTPLUGIN Loaded!")
      

        # 편한 코딩을 위해 action들의 튜플을 만들어 두고
        actions = (
            idaapi.action_desc_t(ACTION_TEST, "TEST POPUP MENU!!!", PopupActionHandler(ACTION_TEST), None, None, 38),
        )

        # action들을 ida에 등록!
        for i in actions:
            idaapi.register_action(i)
            self.reg_actions.append(i.name)


        # 각종 이벤트들을 받아보려면 UIHook이 필요함
        self.ui_hook = UIHook()
        self.ui_hook.hook()

        # 플러그인이 계속 동작하고 있어야함
        return idaapi.PLUGIN_KEEP


    def run(self, arg):
        pass

    def term(self):
        # UIHook 해제
        if self.ui_hook:
            self.ui_hook.unhook()

        # 등록된 action들 해제
        for i in self.reg_actions:
            idaapi.unregister_action(i)
        
        idaapi.msg("term() called!\n")

def PLUGIN_ENTRY():
    return mytestplugin()
   
  

'Study > IDA' 카테고리의 다른 글

[PyQt4] Example  (0) 2021.03.28
IDA Python Plugin  (0) 2021.03.11
IDAPython API 정리 2  (0) 2021.01.19
IDAPython API 정리  (0) 2021.01.12