2013년 7월 30일 화요일

[Android] 디버깅과 리버싱


안드로이드 어플리케이션 파일인 apk 는 dex, resources와 library 로 구성되어 있는 압축파일이다.

여기서 dex 파일은 어플리케이션의 소스 파일이며 class를 거쳐 java 파일로 디컴파일 하면서

어플리케이션 소스를 분석할 수 있다.


1. 디컴파일을 위한 툴 설치

1.ApkTool
- 다운로드 : http://code.google.com/p/android-apktool/downloads/list

2.Dex2Jar
- 다운로드 : http://code.google.com/p/dex2jar/downloads/list

3.Java Decompiler
- 다운로드 : http://java.decompiler.free.fr/?q=jdgui


2. apk 파일 추출

$ adb shell # 추출하고자 하는 apk 파일의 위치를 찾음

$ adb pull /data/app/com.xxx.apk # 파일 추출


3. apk 파일을 디코딩

$ apktool d com.xxx.apk out # asset, res, smali(소스파일), xml, yml 파일을 얻을 수 있음

> java -jar apktool.jar d com.xxx.apk out 

4. Dex2Jar 을 통해 Java 파일 추출

apk 파일을 zip 확장자로 바꾸고 압축 해제해서 classes.dex 파일 추출

$ dex2jar classes.dex # classes.dex.dex2jar.jar 파일을 얻을 수 있음


5. JD-GUI 를 이용해 Java 소스 분석

가끔 Java Decompiler 가 소스를 제대로 디컴파일 하지 못하는 경우가 발생한다.

소스 보기를 하면 // INTERNAL ERROR // 라는 오류 메세지만 뜰 뿐 소스가 보이지 않아 당황스러웠지만,

다른 Java 디컴파일러인 DJ Java Decompiler 를 사용하면 제대로 보인다.


6. java 소스를 참고해 smali 소스를 수정해서 리버싱


7. smali를 다시 컴파일하고 apk 파일 생성

$ apktool b out

ex)

$ adb uninstall ops.black.herpderper
$ apktool b herp patched.apk
alias keytool='java -Dfile.encoding=utf8 sun.security.tools.KeyTool ' // only for mac user
$ keytool -genkey -v -keystore my.keystore -alias anyalias -keyalg RSA -validity 10000
$ jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my.keystore patched.apk anyalias 
$ adb install patched.apk


8. apk 파일 릴리즈 (키 생성 및 사인) - optional

0. only for mac user
alias keytool='java -Dfile.encoding=utf8 sun.security.tools.KeyTool '

1. 키 생성
$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -validity 10000

혹은 eclipse 에서 export->android application 을 통해 생성

2. 키 사인

$ jarsigner -verbose -keystore my-release-key.keystore my_application.apk alias_name


9. 안드로이드 패킷 캡쳐 - optional

carpedm20:/$ adb shell
shell@android:/ $ su
root@android:/ # tcpdump -i rmnet1 -s 0 -w /sdcard/ab.pcap

10. Example


$ adb pull /data/app/com.kakao.talk-1.apk
> java -jar apktool.jar d com.xxx.apk out 
$ adb uninstall com.kakao.group
$ apktool b out patched.apk
$ keytool -genkey -v -keystore my.keystore -alias anyalias -keyalg RSA -validity 10000
$ jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my.keystore patched.apk anyalias
$ adb install patched.apk

2013년 7월 29일 월요일

Paros 윈도우 64bit에서 사용법


웹 request와 response를 분석할때 사용되는 paros 가 윈도우 64비트 환경에서

실행이 안되는 오류가 발생한다.

설치후 pars를 실행시키면 javaw.exe 파일을 찾을 수 없다는 오류가 뜨는데,

자바 경로가 32bit 환경에 맞춰져 있기 때문에 이러한 문제가 발생한다.

paros 바로가기가 \System32\javaw.exe -jar paros.jar 이런식으로 정해져 있을텐데

\SysWOW64\javaw.exe -jar paros.jar 로 바꿔준다면 문제없이 실행된다.

[Python] openCV를 이용해 스도쿠 그림 인식 및 계산 예제




다음과 같은 스도쿠 이미지를


위와 같이 refactor 한 후,


점점 contour 를 조정해 가면서 숫자를 알아낸다


혹은 아래처럼 스도쿠판의 네 꼭지점을 먼저 찾아서 스도쿠 범위를 정하는 방법도 있다




그림 인식에는 openCV 가 사용된다.

코드를 한달 전 정도에 짜서 내용도 잘 기억 안나고, 코멘트도 영어로 단 상태인데,

조만간 수정할 계획이다 :)

# author = 'carpedm20'
import cv2
from cv import *
from cv2 import *
import numpy as np

img =  cv2.imread('sudoku.jpg')

# can remove lots of noises by blur effect
gray = cv2.GaussianBlur(gray,(5,5),0)
#cv2.imwrite('gaussian.jpg',gray)

# change color from RGB image to Gray image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

mask = np.zeros((gray.shape),np.uint8)
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))

close = cv2.morphologyEx(gray,cv2.MORPH_CLOSE,kernel1)
div = np.float32(gray)/(close)
res = np.uint8(cv2.normalize(div,div,0,255,cv2.NORM_MINMAX))
res2 = cv2.cvtColor(res,cv2.COLOR_GRAY2BGR)

# adaptive threshold : taking a best value for a local neighbourhood
# threshold : find treshold taking image as a whole
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
cv2.imwrite('img_thresh.jpg',thresh)

white = Closing[src, DiskMatrix[5]];
srcAdjusted = Image[ImageData[src]/ImageData[white]]

# # of contour by mode
# CV_RETR_EXTERNAL < CV_RETR_LIST < CV_RETR_CCOMP < CV_RETR_TREE
#contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

biggest = None
#biggest = []
max_area = 0
for i in contours:
 # calculate area of contour
        area = cv2.contourArea(i)
        if area > 100:
  # calculates a contour perimeter or a curve lengt
  # closed : True - Flag indicating whether the curve is closed or not
                peri = cv2.arcLength(i,True)
                #peri = cv2.arcLength(i,False)
  # Approximates a polygonal curves with the specified precision.
                approx = cv2.approxPolyDP(i,0.02*peri,True)
                #approx = cv2.approxPolyDP(i,0.02*peri,False)

                if area > max_area and len(approx)==4:
                #if len(approx)>=4:
                        biggest = approx
                        #biggest.append(approx)
                        max_area = area

# -1 : indicating a contour to draw, negative means all contours
# (0,255,0) : RGB
# 3 : width of countour, negative means fill the countours
cv2.drawContours(img, biggest, -1, (0,255,0), 2)

cv2.imwrite('contour.jpg',img)

def rectify(h):
        h = h.reshape((4,2))
        hnew = np.zeros((4,2),dtype = np.float32)

        add = h.sum(1)
        hnew[0] = h[np.argmin(add)]
        hnew[2] = h[np.argmax(add)]

        diff = np.diff(h,axis = 1)
        hnew[1] = h[np.argmin(diff)]
        hnew[3] = h[np.argmax(diff)]

        return hnew

approx=rectify(biggest)
h = np.array([ [0,0],[449,0],[449,449],[0,449] ],np.float32)

retval = cv2.getPerspectiveTransform(approx,h)
warp = cv2.warpPerspective(gray,retval,(450,450))

cv2.imwrite('warp.jpg',warp)

reference : http://opencvpython.blogspot.in/2012/06/sudoku-solver-part-1.html