2011. 8. 15. 08:07

음.. 간만에 쉬는 날이니까.. 오늘도 하나 투척~!

같은 계열사 임에도 불구하고 신한은행, 신한카드 등 다른 어플과는 약간 다른 로직이네요..

개발 외주를 다른데 줬나 ㅡㅡㅋ

아무튼... 신한굿아이는 바로 요부분에서 검사를 해서 분기하네요~


음.. CBZ네용?

지금 조기 노랭이 부분에서 또로로록 점선화살표를 따라가면 굿아이 앱이 좔좔좔좔 잘 돌아가고,
점선을 안따라가믄 "순정이 아니네 홈버튼이 어쩌네 기타 궁시렁 궁시렁...ㅁ나어" 하면서 뒈지는데요..

그럼 요기서 잠깐 쓸데없는 ARM/thumb instruction set을 알아보죵..

CBZ 또는 CBNZ의 syntax는

CBZ [비교되어질 레지스터], 분기할 OFFSET
CBNZ [비교되어질 레지스터], 분기할 OFFSET

으로 이루어 지는데...

CBZ는
CMP [비교되어질 레지스터], #0
BEQ  분기할 OFFSET
과 같고
CBNZ는
CMP [비교되어질 레지스터], #0
BNE 분기할 OFFSET
과 같아부린거죵..

고래면..

지금 조짝에서 딱 보믄... 비교되어질 레지스터는 R5가 될끼고
R5가 0과 같으면 또로로로록 점선을 따라서 살텐데....
R5가 0이 아니면 궁서렁 구렁텅이로 빠지겠네용..

여하튼 결론은 좌우당간... 요놈에 앱을 기냥 탈옥폰에서도 팽팽 쓸라믄
0x33EC까지 진행혔을때 R5에 0이 있던가,
아니믄 0x33EC를 기냥 기냥 B라는 무식한 눔으루다가 대체를 하던가 기냥
뭐 방법이야 개성대로~

글구 엄청나게 휘황찬란하고 뽠따스틱한 ARM의 세상에 대하여 완죤하게 알고싶으신 분은 요리로..

ARM Information Center : http://infocenter.arm.com/help/index.jsp

숑숑..


Posted by 땡보
2011. 8. 13. 08:33

흠.. 오늘은 요새 오르락 내리락 하는 주식 차트를 확인하는데 자주 사용하는 앱인.. 증권통입니다.

증권통 앱이 탈옥 여부를 체크하는 핵심 로직 부분은 바로 요 부분.. 입죠..


수정포인트는 몇군데 일까요?? ㅋ

여러포인트가 될 수도 있고 한포인트가 될 수도 있겠네요.. 머 그건.. 개성대로~~

숑숑~
Posted by 땡보
2011. 8. 5. 18:57
요샌 회사가 늠흐 늠흐 바빠가가 틈이 나질 않네요.

머.. 일단 그나 저나 IDA는 쥔짜로 날로 날로 좋아지누무나...

요기가 바로 현대카드 탈옥 체크루틴 핵심부 입죠..
 


그럼...

Posted by 땡보
2011. 6. 8. 13:18

ARM Opcode

By antelox

Strong ARM (SA1110) Opcodes


MOV r0, r0 is traditionally used in ARM code, which has the opcode 0xe1a00000
MOV r8, r8 is used in THUMB code (opcode 0x46c0)


Command Hex Example
——————————————————————————————————–
B xxxxxxEA branch
BEQ xxxxxx0A b if zero (Z)
BNE xxxxxx1A b if not equal (-Z)
BGE xxxxxxAA b if greater or equal (N*V/-N*-V)
BHI xxxxxx8A b if higher (-C*-Z)
BLT xxxxxxBA b if less than (N*-V/-N*V)
BCC xxxxxx3A b if carry clear
BCS xxxxxx2A b if carry set
BVC .
BVS .
BPL xxxxxx5A
BMI xxxxxx4A b if negative, set N
BHS .
BLO .
BLS xxxxxx9A b if lower or same (C/Z)
BGT xxxxxxCA b if greater than (N*V*-Z/-N*-V*-Z)
BLE xxxxxxDA b if less or equal (Z/N*-V/-N*V)

00022714 B loc_22734 06 00 00 EA
000226B8 BLE loc_226E4 09 00 00 DA

——————————————————————————————————–

BL xxxx00EB
BLEQ xxxx000B

——————————————————————————————————–

MOV (reg,value) xxxxA0E3 Mov R1,#0 0010A0E3
Mov R0,#1 0100A0E3
MOVEQ (reg,value) xxxxA003 Moveq R5, #0 0050A003
MOVNE (reg,value) xxxxA013
MOVGE (reg,value) xxxxA0A3
MOVHI (reg,value) xxxxA083

7F 0C A0 E3 MOV R0, #0x7F00
27 3B A0 E3 MOV R3, #0x9C00

value = erste 2 bytes * mX (x = Byte 4)

m1 := $40000000;
m2 := $10000000;
m3 := $4000000;
m4 := $1000000;
m5 := $400000;
m6 := $100000;
m7 := $40000;
m8 := $10000;
m9 := $4000;
mA := $1000;
mB := $400;
mC := $100;
mD := $40;
mE := $10;
mF := $4;

——————————————————————————————————–

MOV (reg,reg) xxxxA0E1 Mov R4,R0 0040A0E1
Mov R7,R1 0170A0E1
MOVEQ (reg,reg) xxxxA001
MOVNE (reg,reg) xxxxA011

00 38 A0 E1 MOV R3, R0,LSL#16
23 38 A0 E1 MOV R3, R3,LSR#16

——————————————————————————————————–

MOVS R10, R11,ASR#31 CB AF B0 E1
MOVS R11, R1,ASR#31 C1 BF B0 E1

——————————————————————————————————–

CMP (reg,val) 00 00 53 E3
CMP R0,#0 00 00 50 E3
CMP R5,#0 00 00 55 E3
CMPEQ R3,#1 01 00 53 03

——————————————————————————————————–

CMP (reg,reg) xx xx 5X E1
CMP R0,R3 03 00 50 E1

——————————————————————————————————–

LDR R0,[R1,#0x38] 38 00 91 E5
LDR R0,[R5] 00 00 95 E5
LDR R2, [R3] 00 20 93 E5
LDR R1, [R6] 00 10 96 E5

LDRB R2,[R0,#2] 02 20 D0 E5

LDRSH R1, [R6,#0x54] F4 15 D6 E1
LDRSH R1, [R6,#0x56] F6 15 D6 E1

LDRSB R3, [SP,#2] D2 30 DD E1

——————————————————————————————————–

STR R0,[R7] 00 00 87 E5

STRB R1,[R0,R3] 03 10 C0 E7
STRB R11,[LR] 00 B0 CE E5
STRB R11,[LR,#1] 01 B0 CE E5

STRH R3, [R4,#0xC] BC 30 C4 E1
STRH R3, [R4,#0xE] BE 30 C4 E1
STRH R3, [R1] B0 30 C1 E1

——————————————————————————————————–

ORR R3,R3,#0xC 0C 30 83 E3
ORR R3,R3,#0x3C 3C 30 83 E3
ORRS R1, R1, #0×80 80 10 91 E3
ORRS R3, R2, R3,LSL#8 03 34 92 E1
ORRS R5, R2, R3,LSL#8 03 54 92 E1

——————————————————————————————————–

ADD R3, R2, R3 03 30 82 E0
ADD R2, R2, #1 01 20 82 E2
ADD R1, R1, #4 04 10 81 E2
ADD SP, SP, #4 04 D0 8D E2

——————————————————————————————————–

SUB SP, SP, #0×38 38 D0 4D E2
SUB R3, R11, R0 00 30 4B E0

——————————————————————————————————–

ANDS R3, R10, #0xFF FF 30 1A E2
ANDS R3, R0, #0xFF FF 30 10 E2

AND R10, R9, R10 0A A0 09 E0
AND R10, R4, R10 0A A0 04 E0
AND R11, R11, #0xF8 F8 B0 0B E2

——————————————————————————————————–

MUL R11, R2, R4 92 04 0B E0
MUL R9, R11, R3 9B 03 09 E0
MUL R0, R2, R0 92 00 00 E0

——————————————————————————————————–

RSBMI R10, R1, #0 00 A0 61 42
RSBGT R6, R1, R4 04 60 61 C0
RSBMI R4, R2, #0 00 40 62 42

——————————————————————————————————–

RET 0EF0A0E1

——————————————————————————————————–
Virtual NOP MOV R0, R0 00 00 A0 E1

LDREQ R3, [R7,#0x10] = 10 30 97 05
LDREQ R0, [R3,#0x8] = 08 00 93 05

From Fravia‘s site.

Posted by 땡보
2011. 5. 29. 22:06

흠... 2007년경 아주 오래 전에 진행했던 작업을 하나 올려보고자 한다.. 나름 재미있었던 작업이었다..
(참고로 아래의 내용은 2007년경 작성되어진 내용으로, 현재 운영중인 해당 사이트의 바이너리와는 차이가 있음을 밝혀두며,
 만약 문제가 될 소지가 있거나, 삭제 요청이 들어올 경우 즉시 삭제 처리 할 의향이 있음을 밝혀 둡니다.)

QXile은 일종의 P2P 프로그램으로 유료 결제 또는 공짜 포인트 얻기를 통하여 일정량의 포인트를 획득하고,
해당포인트를 사용하여 여러 자료를 다운받을 수 있는 프로그램이다.

다른 P2P 사이트와는 달리 해당 사이트에서 재밌었던 것은 공짜 포인트를 얻을수 있는 2가지 미니게임을 제공한다는
점이었다. 미니 게임은.. 타자게임과 로또게임이었는데..

타자게임은 이용자가 채팅방에 들어가서, 일정 시간마다 랜덤하게 뿌려지는 문구를 모든 사용자가 빠르게 타이핑하여
순위를 메겨 순위별로 일정 포인트를 지급하여주는 방식이었고(아래 그램),

로또게임은 채팅방에 있는 사람들이 1부터 20까지의 숫자를 입력하여, 일정시간마다 추첨이 행해지고 선택한 20개 숫
자중 5개가 일치할시에 150만 포인트, 2등(4개일치) 3만 포인트, 3등(3개 일치) 300포인트를 지급하는 게임이었다.(아래그림)

위의 두 게임을 짬짬히 하며 재미를 더해갈 즈음.. 자동으로 플레이를 해주는 프로그램을 만들어 볼까라는 생각에서 시작해보았다.

먼저 타자게임을 어떻게 구현해볼까 생각하다.. 첫번째 든생각이 랜덤 문장이 나오는 캡션창의 문구를 후킹해 구현해볼까를
생각해보고 덤벼 봤는데 녹녹치가 않았다. 내공이 후달려서 그런건지..

어쨌든 방법을 바꾸어 캡션바 객체의 캡션명 후킹이 아닌 직접적으로 해당 랜덤문자열이 생성되어지는 주소 공간을 찾기로 하고
몇일 삽질하다가 결국은 랜덤 문자열이 생성되어 저장되어지는 주소 공간을 찾아 낼 수 있었다..(ollydbg 이용)

0041893A   .  8BC8          mov     ecx, eax
0041893C   .  FF52 0C       call    near dword ptr ds:[edx+C]
0041893F   .  83C0 10       add     eax, 10
00418942   .  894424 18     mov     dword ptr ss:[esp+18], eax  // 이부분
00418946   .  8B4424 10     mov     eax, dword ptr ss:[esp+10]
0041894A   .  8B0F          mov     ecx, dword ptr ds:[edi]
0041894C   .  50            push    eax
0041894D   .  51            push    ecx
0041894E   .  8D5424 20     lea     edx, dword ptr ss:[esp+20]
00418952   .  68 64544500   push    QXile.00455464                ;  ASCII "제한속도: %s(타/분)문구: /%s"
00418957   .  52            push    edx

위의 부분에서 OFFSET 418942 부분을 보면 랜덤하게 생성되어진 문자열의 주소값을 불러오는 부분을 찾아 내었지만 다음
문제에 봉착하게 되었다. 바로 문자열이 상대주소 OFFSET에 저장되어진다는 점이었다 ㅡㅡ; 따라서 문자열이 저장되어
지는 공간을 절대주소로 지정하기 위해서 위의 부분을 아래와 같이 인라인 패칭 하였다.

먼저 프로그램상의 코드 영역중 빈공간을 찾아서(OFFSET 4500E3에서 찾아 낼 수 있었다.) 해당영역으로 강제 분기 시킨후,

0041893A   .  8BC8          mov     ecx, eax
0041893C   .  FF52 0C       call    near dword ptr ds:[edx+C]
0041893F   .  83C0 10       add     eax, 10
00418942      E9 9C770300   jmp     QXile.004500E3
00418947      90            nop
00418948      90            nop
00418949      90            nop
0041894A   >  8B0F          mov     ecx, dword ptr ds:[edi]
0041894C   .  50            push    eax
0041894D   .  51            push    ecx
0041894E   .  8D5424 20     lea     edx, dword ptr ss:[esp+20]
00418952   .  68 64544500   push    QXile.00455464                                  ;  ASCII "제한속도: %s(타/분)문구: /%s"
00418957   .  52            push    edx


아래와 같이 생성된 문자열의 주소 값을 가지고 있는 eax레지스터의 주소값에 있는 문자열을 내가 원하는
빈공간에 복사하는 구문을 아래와 같이 구현하였다.

004500DE      00            db      00
004500DF      00            db      00
004500E0      00            db      00
004500E1      00            db      00
004500E2      00            db      00
004500E3   .  894424 18     mov     dword ptr ss:[esp+18], eax
004500E7   .  8B4424 10     mov     eax, dword ptr ss:[esp+10]
004500EB   .  A3 2A014500   mov     dword ptr ds:[45012A], eax
004500F0   .  60            pushad
004500F1   .  B9 00000000   mov     ecx, 0
004500F6   >  8A1408        mov     dl, byte ptr ds:[eax+ecx]
004500F9   .  80FA 00       cmp     dl, 0
004500FC   .  74 03         je      short QXileCha.00450101
004500FE   .  41            inc     ecx
004500FF   .^ EB F5         jmp     short QXileCha.004500F6
00450101   >  890D 36014500 mov     dword ptr ds:[450136], ecx
00450107   .  A1 2A014500   mov     eax, dword ptr ds:[45012A]
0045010C   .  8D30          lea     esi, dword ptr ds:[eax]
0045010E   .  8D3D 3D014500 lea     edi, dword ptr ds:[45013D]
00450114   .  8B0D 36014500 mov     ecx, dword ptr ds:[450136]
0045011A   .  F3:A4         rep     movs byte ptr es:[edi], byte ptr ds:[esi]
0045011C   .  61            popad
0045011D   .^ E9 2888FCFF   jmp     QXileCha.0041894A
00450122      00            db      00
00450123      00            db      00
00450124      00            db      00
00450125      00            db      00
00450126      00            db      00
00450127      00            db      00
00450128      00            db      00
00450129      00            db      00
0045012A   .  00000000      dd      00000000                                           ;  Original String Address
0045012E      00            db      00
0045012F      00            db      00
00450130      00            db      00
00450131      00            db      00
00450132      00            db      00
00450133      00            db      00
00450134      00            db      00
00450135      00            db      00
00450136   .  00000000      dd      00000000                                           ;  String length
0045013A      00            db      00
0045013B      00            db      00
0045013C      00            db      00
0045013D      00            db      00                                                 ;  Real String Address

먼저 랜덤문자열의 주소값을 가지고 있는 eax레지스터를 내가 지정한 빈공간 OFFSET 45012A에 저장시킨후,
스택 꼬임 방지를 위해 스택을 백업한 후(pushad),
생성되어진 랜덤 문자열의 끝문자 '0'를 검색하기 위해 루프를 돌려 문자열의 길이를 파악한다.
카운팅 되어진 문자열 길이는 ecx레지스터에 저장하고, 이 길이 만큼을 원문자열 주소시작부 부터 불러내다가,
정해놓은 공간인 OFFSET 45013D에 복사하도록 한다. 복사가 끝나면 아까 백업한 레지스터를 복원시키고(popad)
위의 강제 분기시켰던 이후로 흐름을 돌린다.

이렇게 하여 계속해서 변화하는 주소값에 저장되어지던 문자열을 프로그램의 빈공간인 고정 OFFSET 45013D에
계속해서 복사 할 수 있게 되었다.

이렇게 복사 하여놓은 절대주소 값은 항상 고정되어 있으므로 향후에 만들어질 오토프로그램에서 아래와 같이
Private Const Add_TypeStr = &H45013D        '문자열 시작 주소
Private Const Add_TypeStrLen = &H450136     '문자열 길이
선언하여 사용하였다.(언어는 VB 6.0)

먼저 프로그램 선언부에 다른 프로그램의 메모리 영역을 접근하기 위하여 아래와 같은 API 선언을 하였다.(물론 실제 소스에선
부수적인 처리를 위해 많은 API들이 추가 선언 되었다.)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function VirtualProtectEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function VirtualAlloc Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long

여기서 접근 권한을 해제하는데 사용되어지는 API는 VirtualProtectEx이며,

Private Const PROCESS_VM_READ = (&H10)
Private Const PROCESS_VM_WRITE = (&H20)
Private Const PROCESS_VM_OPERATION = (&H8)
Private Const PROCESS_QUERY_INFORMATION = (&H400)
Private Const PROCESS_READ_WRITE_QUERY = PROCESS_VM_READ + PROCESS_VM_WRITE + PROCESS_VM_OPERATION + PROCESS_QUERY_INFORMATION

Private Const PAGE_READWRITE = &H4&

같이 위와같은 상수들도 선언하여 주었다.

선언후에 프로그램 핵심부에서는 아래와 같이 위의 고정 OFFSET에서 문자열의 길이와 내용을 불러낼 수 있었다.
    '문자열 길이를 저장한 주소공간 변수인, Add_TypeStrLen과 윈도우 캡션명(핸들을 얻기 위함)을 넘기고

    Int_ReadLen = GetLong(Add_TypeStrLen, "큐X일 채팅(게임)")
    '이상하게 값중에 쓰레기 값이 오는것이 있어.. 그걸 걸래내기 위함
    If (Int_ReadLen > &H50) Or (Int_ReadLen < &H10) Then
        Text1.Text = "(" & Int_ReadLen & ") 값이 작거나 커 처리 하지 않습니다!!" & vbCrLf
        Exit Sub
    End If
    '읽어온 문자열 길이만큼 빈공간 생성
    Str_Return = Space$(Int_ReadLen)
    '읽어온 길이와 실제 문자열이 저장된 공간의 주소값을 넘겨 문자열을 가져옴
    Str_Return = GetString(Add_TypeStr, Int_ReadLen, "큐X일 채팅(게임)")
    Str_Return = Trim(Str_Return)
    Lbl_TypeString.Caption = Str_Return

아래는 위에서 사용되어진 사용자 함수의 원형 별거 없음 캡션으로 핸들구해서 pid구한 후 해당 pid에
고정 OFFSET 값에 저장되어진 값들을 불러내서 리턴혀주는게 다인 뭐 그냥 그런 사용자 함수.

Private Function GetString(address As Long, Length As Long, WinTitle As String) As String
   
    hWin = FindWindow(vbNullString, WinTitle)
    Call GetWindowThreadProcessId(hWin, pid)

    hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
    sBuffer = String(Length, 0)
    test = ReadProcessMemory(hProcess, ByVal address, ByVal sBuffer, ByVal Length, 0)
    GetString = sBuffer
    CloseHandle hProcess
   
End Function

Private Function GetLong(address As Long, WinTitle As String) As Long
   
    hWin = FindWindow(vbNullString, WinTitle)
    Call GetWindowThreadProcessId(hWin, pid)

    hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
    test = ReadProcessMemory(hProcess, ByVal address, longBuffer, ByVal 4, 0)
    CloseHandle hProcess
    GetLong = longBuffer

End Function

요래저래 해서 문자열까지 불러오는데 성공....

Private Sub Send_TypeStr(ByVal Send_Str As String, ByVal str_len As Long)
   
    Dim Chk_Flag As Long
   
    'Chk_Flag = SendMessage(ChatBox_hWnd, WM_SETTEXT, -1, ByVal CStr(Send_Str))
    'Call Delay(1)
    'Chk_Flag = PostMessage(ChatBox_hWnd, WM_KEYDOWN, vbKeyReturn, 0)
    'Call Delay(1)
    'Chk_Flag = PostMessage(ChatBox_hWnd, WM_KEYUP, vbKeyReturn, 0)
   
    Chk_Flag = SendMessage(ChatBox_hWnd, WM_SETTEXT, -1, ByVal CStr("/" & Send_Str))
    'Debug.Print TypeSpeed_Interval(Val(Txt_TypeSpeed.Text), str_len)
    Call Delay(TypeSpeed_Interval(Val(Txt_TypeSpeed.Text), str_len))
    Chk_Flag = PostMessage(ChatBox_hWnd, WM_KEYDOWN, vbKeyReturn, 0)
    Chk_Flag = PostMessage(ChatBox_hWnd, WM_KEYUP, vbKeyReturn, 0)
    DoEvents

End Sub

Private Function TypeSpeed_Interval(ByVal Input_TypeSpeed As Long, str_len) As Single
   
    TypeSpeed_Interval = Int(60 * (LenB(Lbl_TypeString.Caption))) / Input_TypeSpeed
   
End Function

위의 사용자 함수를 하나 더 맹글고 문자열과 길이를 받아(길이는 그냥 단순히 원하는 타수를 비스무레하게 만들기위한
딜레이를 주기위한 파라메터)

SendMessage API를 사용하여 가져온 문자열을 채팅창에 뿌려준 후, 길이로 대충 계산한 시간만큼 딜레이 시키고,
PostMessage API를 사용하여 엔터키까지 날려주면 끝.. ㅡㅡ;;

써놓고 나니 횡설 수설인듯.. 암턴 그리하야... 만들어진 플그램 화면을 보면 아래와 같음.. 아... 이놈에 무지한 디자인 감각..

아쉽게도 너무 오래된 내용이어서 실제 돌아가는 화면을 캡쳐 떠놓진 못했지만... 머 그때 당시엔 훌륭하게 동작하였음...

케케케 완죤 재미난 분석작업 이었음..

아... 그나저나 두게임 다 한방에 올릴라고 했는데 겁나 길어져서 담에 올려야 겠음...

그럼 다들 즐거운 밤들 되셔욤~~

바이바이~~


Posted by 땡보
2011. 5. 21. 12:45
 <key>SignerIdentity</key>
 <string>Apple iPhone OS Application Signing</string>
Posted by 땡보
2011. 5. 21. 12:30

ㅡㅡ;; 3일을 뻘짓했네 아놔..... 이눔에 고난의 길.... 
attach 해놓고 백날 수정하면 ㅡㅡ;;
수정된 이미지가 먹히냐!! ㅡㅡ;; (띵킹을 좀 하자 ㅡㅡ;;)


__text:00005434                 BLX     _objc_msgSend
__text:00005438                 LDR     R1, =(off_3472C8 - 0x5440)
__text:0000543A                 LDR     R2, =(cfstr_Ahn_3379024345 - 0x5442)
__text:0000543C                 ADD     R1, PC
__text:0000543E                 ADD     R2, PC          ;
__text:00005440                 LDR     R1, [R1]
__text:00005442                 STR     R0, [SP,#0x88+var_74]
__text:00005444                 BLX     _objc_msgSend   ; --2011/05/21(토) hElLoOnG--
__text:00005444                                         ; 요기서 탈옥 루틴 검사후 R0 레지스터에 결과값 반영!!
__text:00005444                                         ; 결과값은 탈옥인경우 R0 = 1, 아닌경우 R0 = 0
__text:00005444                                         ;
__text:00005444                                         ; 위의 결과를 아래에서 CMP R0, #1로 판별후, CPSR컨디션
__text:00005444                                         ; 에따라서 BNE(Not Equal)이면 OFFSET 5546으로 분기!!
__text:00005444                                         ;
__text:00005444                                         ; 또한 5546으로 분기후에 한번더 CMP.W R0, 0xFFFFFFFF
__text:00005444                                         ; 으로 R0값을 한번더 판별한다.
__text:00005444                                         ;
__text:00005444                                         ; 그럼 가장 수정폭이 작게 하려면.. 어차피 R0에 1이
__text:00005444                                         ; 들어 있는 상황이므로, 이는 아래 비교 루틴에서도
__text:00005444                                         ; 다른 값이다. 따라서 CMP R0, #1을 #1이 아닌 다른 값
__text:00005444                                         ; 으로 수정해서 이 로직만 통과 하면 자동으로 아래
__text:00005444                                         ; 비교 구문은 우회 할 수 있다. 따라서 우리의 목표
__text:00005444                                         ; 지점인 OFFSET 565c에 도달 할 수 있다.
__text:00005448                 CMP     R0, #1
__text:0000544A                 BNE     loc_5546
__text:0000544C                 LDR     R0, =(unk_348DB8 - 0x5456)
__text:0000544E                 LDR     R1, =(off_3472C4 - 0x5458)
__text:00005450                 LDR     R6, =(cfstr_Jailbreakmsg - 0x545E)
__text:00005452                 ADD     R0, PC
__text:00005454                 ADD     R1, PC

그럼 CMP R0, #1의 OPCODE(0x2801)를 CMP R0, #0(0x2800)으로 바구면 끝!!

Posted by 땡보
2011. 4. 18. 00:01
MOV r0, r0 is traditionally used in ARM code, which has the opcode 0xe1a00000
MOV r8, r8 is used in THUMB code (opcode 0x46c0)

원문 : http://stackoverflow.com/questions/1875491/nop-for-iphone-binaries


Posted by 땡보