[컴][디버그] 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/

 

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.

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

font change in sublime text2

 

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

http://imjuni.tistory.com/559

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


아직 부정확한 부분이 있어서, 정리차원으로 적어놓는다. 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 에서 navigation history 기능 추가 하기

How to add the navigation history function in sublime text2,  or navigation history plug in

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

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

See Also


  1. Using Sublime Text as your IDE,  The Chromium Projects : project 관련 기능들이 잘 나와 있다.
    • source code indexing using Ctags

[컴][웹][자바스크립트] 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/