본문 바로가기

[Study & Job]/[기타]

후킹관련

windows event 를 흉내내서 macro 를 만들려고 한다.

참고가 될 만한 사항들을 모아놨다.



Windows sibling window 에서 next window 의 handle 얻어오기.

d = win32gui.GetWindow(c, win32con.GW_HWNDNEXT)

enum 값

win32con.GW_HWNDFIRST = 0   

win32con.GW_HWNDLAST = 1   

win32con.GW_HWNDNEXT = 2   

win32con.GW_HWNDPREV = 3   

win32con.GW_OWNER = 4   

win32con.GW_CHILD = 5   

win32con.GW_ENABLEDPOPUP = 6



Window handle 얻어오는 함수 - class name 과 window caption 을 참조해서.


def getWindowHandle(className, winCaption, wait):

    while 1:

        windows = []

        win32gui.EnumWindows(_windowEnumerationHandler, windows)

        for hwnd, windowText, windowClass in windows:

            # Get the handle of 'Exe Binary Builder'

            if windowClass == className and windowText == winCaption:

                print '%s handle = %d' % (windowText, hwnd)

                return hwnd

                

        if wait is True:

            time.sleep(1)

        else:

            return None


마우스 클릭은 아래와 같이 해주면 된다.

 # mouse click

win32gui.SendMessage(btnHandle, win32con.WM_LBUTTONDOWN, 0, 0)

win32gui.SendMessage(btnHandle, win32con.WM_LBUTTONUP, 0, 0)


ID 로 관련 control 찾는 법

browseHandle = win32gui.GetDlgItem(hwnd, ID_BTN_BROWSE_PARTITION)


Class Name 과 Window Caption 으로 찾는법

Class Name 이 'Button' 이고, Window Caption 이 'DZ Builder'인 경우

btnDzBuilder = win32gui.FindWindowEx(hwnd, None, "Button", "DZ Builder")


Edit 창에 글자 입력

win32gui.SendMessage(filenameEdit, win32con.WM_SETTEXT, len(rawfilename)+1, rawfilename) 

이 때 주의할 점은 rawfilename 등의 변수 type이 str 이어야 한다. uncode 인 경우는 str 으로 encoding 을 해줘야 한다.




Dialog 창 처리


def processPopup(imagefolder, dzfile):

    windows = []


    time.sleep(2)

    win32gui.EnumWindows(_windowEnumerationHandler, windows)

    for hwnd, windowText, windowClass in windows:

        if windowText == 'DZ Image Builder' and windowClass == '#32770':




def main():

    ...

    ..

    dzfile = 'test-gang.bin'

    thread.start_new_thread(processPopup, (imagefolder, dzfile,))  # to input and click 'ok'



    btnHandle = win32gui.FindWindowEx(hwnd, None, "Button", "Test")

    # mouse click

    win32gui.SendMessage(btnHandle, win32con.WM_LBUTTONDOWN, 0, 0)

    win32gui.SendMessage(btnHandle, win32con.WM_LBUTTONUP, 0, 0)



SysListView32 의 column 값을 가져올 때

아래 경로에 있는 함수를 가져다 쓰면 된다.

http://stackoverflow.com/questions/1872480/use-python-to-extract-listview-items-from-another-application

marshalling 을 windows 가 자동으로 해주지 못해서, 다른 process에서 접근하려면 위의 방식을 써야고 한다.

EditCtrl 이나 기타 기본적인 control 들은 자동으로 marshaling 을 해주기 때문에 저런 복잡한 방식이 필요없다고 한다.

(참고 : http://bytes.com/topic/c-sharp/answers/258027-getting-listview-items-c-syslistview32-using-sendmessage)


OpenProcess

OpenProcess 로 현재 떠 있는 process에 접근해서 memory 의 값을 읽어올 수 있다.

http://chery.tistory.com/tag/OpenProcess

OpemProcess의 정의 : http://code.snapstream.com/api/bm11/SnapStream.Util.Helpers.Win32.OpenProcess.html


VirtualAlloc

http://msdn.microsoft.com/en-us/library/aa366890%28VS.85%29.aspx


WriteProcessMemory

http://msdn.microsoft.com/en-us/library/ms681674%28VS.85%29.aspx


LVITEM struct

http://msdn.microsoft.com/en-us/library/bb774760%28VS.85%29.aspx



ComboBox 관련

참고 : http://msdn.microsoft.com/en-us/library/bb775792%28VS.85%29.aspx

http://www.brunningonline.net/simon/blog/archives/000664.html



handle 얻어오는법

comboBoxHandle = win32gui.FindWindowEx(hwnd, 0, "ComboBox", None)


count 얻는 법

comboBoxCount = win32gui.SendMessage(comboBoxHandle, win32con.CB_GETCOUNT, None, None)

참고 : http://msdn.microsoft.com/en-us/library/bb775841%28v=VS.85%29.aspx


현재 가리키고 있는 item 의 index

index = win32gui.SendMessage(comboBoxHandle, win32con.CB_GETCURSEL, None,None)


list 내용중 'aa.exe' 가 있는지 찾을 때, ret 가 1이면 True 이다.

ret = win32gui.SendMessage(comboBoxHandle, win32con.CB_FINDSTRING, -1, 'aa.exe')


text 얻어오는 방법(linetext 로 가져온다)

linetext = "".ljust(255)

linelength = win32gui.SendMessage(hwnd, win32con.CB_GETLBTEXT, itemIndex, linetext)

이때 linetext 는 buffer 이기 때문에 text 길이 만큼의 size 를 이미 확보하고 있어야 한다.

그래서 linetext = "".ljust(255)을 해준다. 보다 확실한 buffer size 를 위해서는 CB_GETLBTEXTLEN 를 이용하자.


ComboBox list 의 모든 item 얻어오는 함수.(참고:http://www.brunningonline.net/simon/blog/archives/000664.html

)


def getComboboxItems(hwnd):


    result = []

    

    itemCount = win32gui.SendMessage(hwnd, win32con.CB_GETCOUNT, 0, 0)

    for i in range(itemCount):

        itemLen = win32gui.SendMessage(comboBoxHandle, win32con.CB_GETLBTEXTLEN, i, None)

        linetext = "".ljust(itemLen)    # you don't have to concern 'null' here

        linelength = win32gui.SendMessage(hwnd, win32con.CB_GETLBTEXT, i, linetext)

        result.append(linetext)


    return result


KeyS troke

def keystroke(hwnd, key):<br clear="none" />    win32gui.SendMessage(hwnd, win32con.WM_KEYDOWN, key, 0)<br clear="none" />    win32gui.SendMessage(hwnd, win32con.WM_KEYUP, key, 0)


Menu command 실행하기

menu id 를 구해서, WM_COMMAND 로 message 를 보내주면 된다.


def runMenuCommand(hwnd, menu_pos, submenu_pos)

    # Run the command on the menu bar

    menu = win32gui.GetMenu(hwnd)

    submenu = win32gui.GetSubMenu(menu, menu_pos)


    menuId = win32gui.GetMenuItemID(submenu, submenu_pos)

    win32gui.SendMessage(hwnd, win32con.WM_COMMAND, menuId, 0)

반응형