[컴][디버그] windows 에서 guard page 설정하기 - memory breakpoint

memory breakpoint using page fault on windwos

 

아직 부정확한 부분이 있어서, 정리차원으로 적어놓는다. PyDbg 부분에 대한 분석 이후에 update 를 해야 할 듯 하다.

 

Procedure

  1. page size 를 알아내고,
  2. page 에 permission 을 설정해서 guard page 처럼 작동하도록 한다.
  3. GUARD_PAGE_EXCEPTION 이 발생한다.
  4. exception handler 에서 다시 page 의 permission 을 돌려놓고(이 부분은 OS가 해준다.[ref. 1]), execution 을 계속 이어나간다.

 

 

Page Size

우리가 다룰 page 의 정확한 사이즈를 구하기 위해서, Operating System(OS) 에 default page size 를 물어봐야 한다. GetSystemInfo() 로 할 수 있다. 이 함수에서 SYSTEM_INFO structure 를 채워주는데 이 structure 가 dwPageSize 를 가지고 있다. 이 값이 default page size 가 된다.

 

Permission

page 정보

page permission 을 조정해 보자. 그러기 위해서 먼저 우리가 breakpoint 를 걸고 싶은 주소에 해당하는 page 의 정보를 가져오자. VirtualQueryEx() 로 가능하다. 이 함수에서 MEMORY_BASIC_INFORMATION structure 에 값이 채워지는데, 이 structure 가 가지고 있는 정보가 memory page 에 대한 정보를 가지고 있다.

 

permission 설정

여기에 있는 BaseAddress 정보가 시작점이 된다. permission 을 설정하는 함수는 VirtualProtectEx() 인데, 여기 2번째 인자로 들어가는 주소로 BaseAddress 를 넣어주면 된다.


guar page 에 access 를 해서 exception 이 발생하면 OS 가 메모리에 있는 그 page 의 exception 을 알아서 제거해 준다. 그래서 굳이 permission 을 제거하는 루틴을 짜지 않아도 괜찮다.

 

 

Demo

 

# source from Gray Hat Python
# edited by namh



memory_breakpoints = {}

creation_flags = DEBUG_PROCESS

# instantiate the structs
startupinfo = STARTUPINFO()
process_information = PROCESS_INFORMATION()

startupinfo.dwFlags = 0x1
startupinfo.wShowWindow = 0x0
startupinfo.cb = sizeof(startupinfo)

kernel32.CreateProcessA(path_to_exe,
None,
None,
None,
None,
creation_flags,
None,
None,
byref(startupinfo),
byref(process_information)):

pid = process_information.dwProcessId
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS,False,pid)

system_info = SYSTEM_INFO()
kernel32.GetSystemInfo(byref(system_info))

page_size = system_info.dwPageSize


mbi = MEMORY_BASIC_INFORMATION()


# Attempt to discover the base address of the memory page
if kernel32.VirtualQueryEx(\
h_process, address, byref(mbi), sizeof(mbi)) < sizeof(mbi):
return False


current_page = mbi.BaseAddress

# We will set the permissions on all pages that are
# affected by our memory breakpoint.
while current_page <= address + size:

# Add the page to the list, this will
# differentiate our guarded pages from those
# that were set by the OS or the debuggee process
guarded_pages.append(current_page)

old_protection = c_ulong(0)
if not kernel32.VirtualProtectEx(\
h_process, current_page, size,\
mbi.Protect | PAGE_GUARD, byref(old_protection)):
return False

# Increase our range by the size of the
# default system memory page size
current_page += self.page_size

# Add the memory breakpoint to our global list
memory_breakpoints[address] = (address, size, mbi)

return True

 


References



  1. Chapter 3, Gray Hat Python
  2. http://www.codeproject.com/Articles/186230/Extending-windbg-with-Page-Fault-Breakpoints

[컴][안드로이드] .Smali 관련 도움되는 사이트들

 

smali 관련 도움이 될 사이트

출처 : ref. 1
  1. Dalvik opcodes
  2. Understanding the Dalvik bytecode with the Dedexer tool, 2009, 12월 2일
  3. Dalvik Notes,
  4. JASMIN USER GUIDE, 1996. 7월.
  5. 다른 disassembler, Dedexer : http://dedexer.sourceforge.net/

java code 를 smali 로 변환시켜 주는 Intellij plugin






References

  1. What's the best way to learn Smali (and how/when to use Dalvik VM opcodes)?, 2011. 3월 11일

[컴] How to install .smali syntax file on Sublime text

sublime text2 / sublime text / smali 파일을 sublime text 에 설치

smali syntax highlighting files for sublime text2

You can download the "Smali.tmLanguage" file on the below link
https://github.com/ShaneWilton/sublime-smali
then follow the instructions on that page.


See Also


  1. Web Development With Sublime Text

[컴] sublime text 2 에서 한글 폰트로 바꾸기



font change in sublime text2


처음 폰트가 한글로 설정이 되어 있지 않다. 그래서 한글이 표현이 안된다. 한글로 수정하는 방법은 아래 경로에 잘 나와있다.
http://imjuni.tistory.com/559

그리고 추가로 EUC-KR 로 된 file 을 열 때 문자가 안깨지게 하기 위해서
ConvertToUTF
라는 package 를 설치하면 된다.

package control 설치

package 를 쉽게 설치하기 위해서는 package control 를 sublime Text 에 설치하면 된다. 이 마저도 손쉽게 할 수 있다.
http://wbond.net/sublime_packages/package_control/installation
이 곳에 가면 나와 있는 설명이지만, 간단하게 설명하면 이렇다.

  1. ctrl + ` (open python console window)
  2. 아래 box 의 내용을 copy 해서 붙여넣고 enter 를 치면, 실행이 된다.
  3. 그러고 밑에 상태표시줄을 잘 보고 설치가 끝났으면 restart 를 하면 된다.
import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print('Please restart Sublime Text to finish installation')

그리고 나면,
Preference >> Package Control
이 생긴다.

ConvertToUTF 설치

이 Package Control 을 실행하고, ConvertToUTF 를 실행시키면 된다.


[컴][디버그] 하드웨어 브레이크포인트 - hardware breakpoint

리버싱 / reverse engineering


아직 부정확한 부분이 있어서, 정리차원으로 적어놓는다. PyDbg 부분에 대한 분석 이후에 update 를 해야 할 듯 하다.


Procedure

  1. thread 를 모두 열거하고(enumerate)
  2. 거기서 CPU context record 를 가져온다.

    DR0 ~ DR3 중에 한 register 를 수정할 것이다. 물론 사용 중이지 않은 녀석을 수정해야 한다. 그렇지 않으면 우리가 원하는 곳에서 멈추지 않을 것이다.
  3. DR0~DR3 에 내가 breakpoint 를 설정하길 원하는 address를 적어놓으면 된다.
  4. 그러고 나서 DR7 register 의 bit 을 flip 해서 breakpoint 를 enable 시키고, type 과 length 를 설정한다.[ref. 1]
  5. hardware breakpoint 를 set 하고 나서는 이 breakpoint 가 걸렸을 때(thrown) 우리가 수행하고 싶은 function(handler) 를 만들어야 한다.

    hardware breakpoint 는 INT1 을 발생시킨다. 그러므로 INT1 부분에서 수정을 해주면 된다.[ref. 1]
코드는 debugger 가 현재 내 debugger 하나만 실행되고 있다는 가정으로 되어있다.

그래서 debugger 내부적으로 hardware_breakpoints(이하 hwbp) 라는 배열을 갖고 있어서 지금 hwbp 가 사용되고 있는지 아닌지에 정보를 가지고 있는다.

Debug register 값 가져오기

우리는 이전에 배운 snapshot 으로 thread 들을 traverse 하면서 그 중에 우리가 원하는 process_id(pid) 를 가진 녀석들(즉, 우리가 원하는 process 가 갖고 있는 thread 들) 의 thread_id 를 구한다.이 구한 thread_id 를 가지고 OpenThread(), GetThreadContext() 를 거쳐서 thread 의 context 를 얻게 된다. 이 부분은 아래 포스트를 참고하자.
windows 에서 thread 의 context 를 가져오는 법 - snapshot
thead_context 를 보면 structure 내부에 아래와 같이 Debug register 변수가 있다.
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;


아마도 thead context structure 에 deubg register 부분이 있는 것으로 봐서는 thread 의 context switching 이 일어날 때 debug register 의 값들도 다시 set 되는 것 같다.(추측)

Debug Register 설정


여하튼 이제 thread_context 에 있는 이 값들을 설정해 줘서 breakpoint 를 지정하면 된다. ref.1 의 DR7 부분을 보면 값을 어떤 값을 지정해야 하는 지 알 수 있을 것이다. 아래는 관련된 python 코드이다.
# Enable the appropriate flag in the DR7
# register to set the breakpoint
context.Dr7 |= 1 << (available * 2)

# Save the address of the breakpoint in the
# free register that we found
if   available == 0: context.Dr0 = address
elif available == 1: context.Dr1 = address
elif available == 2: context.Dr2 = address
elif available == 3: context.Dr3 = address

# Set the breakpoint condition
context.Dr7 |= condition << ((available * 4) + 16)

# Set the length
context.Dr7 |= length << ((available * 4) + 18)

# Set this threads context with the debug registers
# set
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
kernel32.SetThreadContext(h_thread,byref(context))

코드에서도 보는 것처럼 SetThreadContext() 를 통해서 thread context 값을 변경시켜 준다. 여기서는 process 내에서 printf 가 호출될 때마다 interrupt 를 발생시키려고, 모든 thread 의 context 에 있는 debug register 에 printf 주소를 설정해 놓는다.

Demo

windows7 에서 PyDbg 를 가지고 테스트 중인데, hardware breakpoint 는 동작하지 않는다. 이유는 아직인데, process 의 privilege 의 문제이지 않을까? 추측한다. [ref. 4]
# source from Gray Hat Python
# edited by namh

memory_breakpoints = {}
hardware_breakpoints = {}
kernel32 = windll.kernel32
pid = raw_input("Enter the PID of the process to attach to: ")

# attach
kernel32.DebugActiveProcess(int(pid))

# func_resolve
dll = "msvcrt.dll"
function = "printf"

handle  = kernel32.GetModuleHandleA(dll)
address = kernel32.GetProcAddress(handle, function)

kernel32.CloseHandle(handle)



# bp_set_hw
bp_set_hw(address,1,HW_EXECUTE)



# run
debug_event    = DEBUG_EVENT()
continue_status = DBG_CONTINUE

while True :

    if kernel32.WaitForDebugEvent(byref(debug_event),100):
        # grab various information with regards to the current exception.
        thread_id = debug_event.dwThreadId
        h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
        
        context = CONTEXT()
        context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
                        
        context = kernel32.GetThreadContext(h_thread, byref(context))

        
        
                   
        print "Event Code: %d Thread ID: %d" % \
            (debug_event.dwDebugEventCode,debug_event.dwThreadId)
        
        if debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT:
            exception = debug_event.u.Exception.ExceptionRecord.ExceptionCode
            exception_address = debug_event.u.Exception.ExceptionRecord.ExceptionAddress
            
            # call the internal handler for the exception event that just occured.
            if exception == EXCEPTION_ACCESS_VIOLATION:
                print "Access Violation Detected."

            elif exception == EXCEPTION_BREAKPOINT:
                print "[*] Exception address: 0x%08x" % exception_address

                # check if the breakpoint is one that we set
                if not memory_breakpoints.has_key(exception_address):
                    continue_status = DBG_CONTINUE

            elif exception == EXCEPTION_GUARD_PAGE:
                print "Guard Page Access Detected."

            elif exception == EXCEPTION_SINGLE_STEP:
                exception_handler_single_step()
            
        kernel32.ContinueDebugEvent(debug_event.dwProcessId,\
                                 debug_event.dwThreadId, continue_status)



def bp_set_hw(address, length, condition):
    # Check for a valid length value
    if length not in (1, 2, 4):
        return False
    else:
        length -= 1
        
    # Check for a valid condition
    if condition not in (HW_ACCESS, HW_EXECUTE, HW_WRITE):
        return False

    # Check for available slots
    if not hardware_breakpoints.has_key(0):
        available = 0
    elif not hardware_breakpoints.has_key(1):
        available = 1
    elif not hardware_breakpoints.has_key(2):
        available = 2
    elif not hardware_breakpoints.has_key(3):
        available = 3
    else:
        return False

    # We want to set the debug register in every thread
    for thread_id in enumerate_threads(int(pid)):
     h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
     context = CONTEXT()
        context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS

        kernel32.GetThreadContext(h_thread, byref(context))
        


        # Enable the appropriate flag in the DR7
        # register to set the breakpoint
        context.Dr7 |= 1 << (available * 2)

        # Save the address of the breakpoint in the
        # free register that we found
        if   available == 0: context.Dr0 = address
        elif available == 1: context.Dr1 = address
        elif available == 2: context.Dr2 = address
        elif available == 3: context.Dr3 = address

        # Set the breakpoint condition
        context.Dr7 |= condition << ((available * 4) + 16)

        # Set the length
        context.Dr7 |= length << ((available * 4) + 18)

        # Set this threads context with the debug registers
        # set
        h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
        kernel32.SetThreadContext(h_thread,byref(context))

    # update the internal hardware breakpoint array at the used slot index.
    hardware_breakpoints[available] = (address,length,condition)


def enumerate_threads(pid):
              
    thread_entry     = THREADENTRY32()
    thread_list      = []
    snapshot         = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid)
    
    if snapshot is not None:
    
        # You have to set the size of the struct
        # or the call will fail
        thread_entry.dwSize = sizeof(thread_entry)

        success = kernel32.Thread32First(snapshot, byref(thread_entry))

        while success:
            if thread_entry.th32OwnerProcessID == pid:
                thread_list.append(thread_entry.th32ThreadID)

            success = kernel32.Thread32Next(snapshot, byref(thread_entry))
        
        # No need to explain this call, it closes handles
        # so that we don't leak them.
        kernel32.CloseHandle(snapshot)
        return thread_list
    else:
        return False



References



  1. http://i5on9i.blogspot.kr/2013/04/breakpoint.html
  2. Writing a basic Windows debugger, 2011
  3. Writing a basic Windows debugger Part 2
  4. 브레이크 포인트 탐지 기법 :  Part 1. Hardware Breakpoint Detection &amp; Removing

[컴] sublime text 2, 3 에서 프로그래밍을 위한 plugin 설치하기

How to add the navigation history function in sublime text2,  or navigation history plug in / sublime text 에서 file 열기 / sublim text 를 ide 로 사용하기 / navigation history 기능 추가 하기



CodeComplice 

SublimeCodeIntel 대신에 사용하는 녀석이다. 어떤 blog 에서 이녀석을 SublimeCodeIntel 대신에 추천했다. 이녀석을 사용하면, 자동완성기능이 풍부해진다.

그리고 더불어서 함수이름을 알려주는 역할도 해줘서, 아래의 plugin 이 필요없게 된다.

symbol 을 찾아가는 기능도 들어가 있다. sublime text3 의 기본보다는 나은 듯 하다. 하지만 살짝 느리다. (큰 느낌은 없지만) sublime text3 에서는 project 에 포함시켜야 하는 것이지만, 이 CodeComplice 는 설정에 잡아주면 된다.

좀 더 사용해 보니 sublime text3 가 찾아주는 것을 CodeCompilce 가 못찾아주는 경우도 있다. 이유는 정확히 조사해 보지 않았다. 여하튼 그래서 2가지를 같이 사용하는 것이 좋은 듯 하다.

Ctags

사실 sublime text 2 에서는 이녀석이 좀 필요했는데(근데, 아마 이때도 SublimeText CodeIntel 을 알았더라면, 사용하지 않았을지도 모르겠다.) sublime text3 에서는 사용하지 않았다. 기본적으로 CodeIntel 처럼 definition 등 symbol 을 찾아가 주기 때문이다. 참고로, project 내에 있는 것만 찾아준다.
  1. 윈도우 관련 설정 : 지훈현서 : [에디터] SubLime Text 2 & ctags & python coding
  2. windows 7, sublime Text 2 에서 ctags 사용법

함수 이름 알려주는 plugin

이 녀석도 CodeComplice 덕에 필요없어 졌다.
이녀석이 일반적으로 훨씬 잘 동작한다.
  1. akrabat/SublimeFunctionNameDisplay · GitHub
  2. 함수이름을 status bar 에 보여준다.

Navigation history function

요즘 sublime text 라는 새로운 text editor 를 사용하고 있다. 개인적으로 여러가지 기능들이 마음에 들고 있는 중이다. 그런데 navigation history key (cursor history) 가 없어서 plug-in 을 찾아봤다.

아래 경로에 가면, 설치 방법등이 자세히 나와 있다.
https://github.com/timjrobinson/SublimeNavigationHistory


HighlightWords

특정단어에 색을 입혀주는 plug in 이다. 여러개의 단어를 highlight 할 수 있다. 색은 theme 내에 지정된 것들을 사용한다.

Grunt

Grunt 를 사용할 수 있는 plugin 이다.

Emmet

html 을 쉽게 작성할 수 있도록 도와준다.  Expand Abbreviation 을 한 번 보면 쉽게 이해할 수 있다.

PythonPEP8Autoformat

python code rule 에 맞춰서 자동으로 code를 formatting 해준다. lint 를 사용한다면 이녀석은 필수(?) 일지도 모르겠다.


key binding 관련 tip

command 이름 알아내는 방법

console 창(ctrl+`) 에서
sublime.log_commands(True)


간단한 plugin 만들어서 key binding 하는 법


SideBarEnhancements

이녀석은 sublime text 3 에서만 동작한다. 이녀석을 사용하면, side bar(왼쪽에 있는 file tree) 에서 file 위에서 context menu 를 부를 때 다양한 작업을 할 수 있다.

개인적으로는 search 의 범위등을 정하기가 편하고, file 의 copy/paste 가 좋다.


저장, Plugin 및 세팅 저장

이렇게 열심히 해 놓은 setting 질? 을 다시 하려면 시간이 어마어마 걸린다. 그러니 어디다 잘 저장해 놨다가 다시 copy 해서 사용하면 된다.


package 저장

아래 경로에 있는

  • Packages
  • Installed Packages

를 저장한다.

그리고 어딘가 file 공유 되는 곳에 올려놓자. 그리고 다음에 사용할 때는 다시 아래 folder 에 풀어놓으면 된다.
  • c:\Users\<user_name>\AppData\Roaming\Sublime Text 3

이건 내가 사용하는 package 묶음 이다.


dropbox

보통 dropbox 로 해 놓고, 동기화 시켜서 쓰는 모양이다.

  • pros : 자꾸 설정이 바뀌게 되는 경우라면, 이 방법이 편할 듯 하다.
  • cons : 개인적으로 더 불편하다고 생각된다. dropbox 동기화를 위해 dropbox tool 을 설치하는 일을 또 해야 하고, 설치한 path 를 다시 맞춰야 한다. 
    좀 더 생각해 보니, dropbox 가 있으면, 굳이 설정을 맞추지 않아도 어딘가에 올려놓기 용으로 사용하면 될 듯 하다. 그리고나서 필요할 때는 web 으로 들어가서 download 해서 사용해도 될 듯 하다.




See Also

  1. Using Sublime Text as your IDE,  The Chromium Projects : project 관련 기능들이 잘 나와 있다.
    • source code indexing using Ctags
  2. theme 편집 도구 : http://tmtheme-editor.herokuapp.com/#/theme/Monokai
  3. symbolic locations of search scope for sublime text 2: http://docs.sublimetext.info/en/latest/search_and_replace/search_and_replace_files.html#search-scope
  4. macro 등록 : Macros — Sublime Text Unofficial Documentation
  5. Anaconda : turns your Sublime Text 3 into a full featured Python development IDE
  6. Turning Sublime Text Into a Lightweight Python IDE — training.codefellows 1.0 documentation : python 개발을 위한 설정

Reference

  1. Sublime Text 2 tips for Python and web developers

[컴][웹][자바스크립트] TypeScript, javascript 를 쉽게 배워보자.


TypeScript 라는 것을 접하게 되었다.

홈페이지에 가면, 설명과 데모(Demo) 를 보여주는 동영상이 있는데, 동영상을 한 번 봐도 이해가 된다.

TypeScript 의 목적은
  • "type 에 대한 정의(declaration)" 과
  • "class 같은 구조적인 syntax" 의 제공
인 듯 하다. 물론 이것은 개인적인 생각이다.^^;;;

실제로 TypeScript 홈페이지에서는 TypeScript 를 아래처럼 정의했다.
TypeScript is a language for application-scale JavaScript development.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
TypeScript 홈페이지에서 얘기하는
  • 개발의 용이성에 대한 이득(development tools 에서 type checking 이 가능해져서 자동완성 autocompletion 등이 가능해 지는 듯 하다.)
  • 그리고 모듈(module) 같은 구조를 만들기 쉽게 만들어 놓은 점
등이 주요한 장점이 아닐 가 싶다.

그리고 그에 더해서 이 TypeScript 를 이용하면 다른 OOP programming 에 익숙한 개발자들에게 JavaScript 에 좀 더 쉽게 적응할 수 있도록 해줄 듯 하다.

TypeScript Overview

일단 TypeScript 에 대한 개괄적인 이해와 사용법은 동영상을 한 번 보기를 권장한다.

대략적으로 얘기하면 TypeScript 는 javascript 에 특정한 feature 를 추가한 것이라고 보면 된다. 그래서 .ts 를 작성하면 이것을 compile 해서 TypeScript 로 작성된 source code 를 javascript 로 변환하게 된다. 즉, 최종 결과물은 javascript(.js) 이다.

굳이 비유를 하자면, c/c++ preprocessor 같은 역할을 한다고 보면 될 듯 하다.

여하튼 jQuery, Nodejs 등에 대한 type 도 제공하고, 자신이 원하는 type 등을 만들 수 있어서 Autocompletion 등에 유용하게 사용할 수 있을 듯 하다.




image
< TypeScript 개념도 >

Play

TypeScript 는 홈페이지에서 바로 사용해 볼 수 있다. 아래링크로 가서 사용법을 확인할 수 있는데, 이 페이지를 이용해서 오히려 javascript 에서 일반적인 OOP 의 syntax 를 어떻게 구현하는 지 배울 수도 있다. ^^
http://www.typescriptlang.org/Playground/