如何破解Pocket PC (for ARM)软件
2010年04月17日
比较PC下的软件,Pocket PC上软件的破解是比较简单的。如果你有windows下软件的破解经历,那只要熟悉ARM汇编就够了。
一. 所需知识
1.熟悉C语言和ARM汇编语言。
2.有Windows API编程的经验。
二. 工具
1. Embedded VC++或者VS.NET 2005,用于动态调试待破解程序;
2. IDA Pro,最新版4.9,需要全版,这样能反汇编不同类型CPU的程序,用于静态分析;
3. ResHacker,用于查看资源,找出敏感的字符串;
4. 二进制编辑器,如UltraEdit,WinHex等,用于修改程序;
5. 一种ARM的编译器,如EmbestIDE for ARM、ADS,SDT等,可以用于写一小段汇编代码,再嵌入到目标程序中,也可以用来熟悉ARM指令;
6. 最好有一个pocket pc的设备(ARM CPU),有了vs.net 2005没有设备也可以:)
三. 注册码验证方式与破解方式
当我们输入一个软件的注册码时,软件必须与正确的注册码相比较,才能判断输入的正确与否,下面是常用的注册码验证方法。
1.将owner name或email运算得到正确的注册码,再和输入的注册码比较;
RealKeyCode = f(owner name/email);
If( inputKeyCode == RealkeyCode)
“注册成功”
else
“注册失败”
要强制破解,可以跳过inputKeyCode == RealkeyCode判断,直接执行“注册成功”。如果要做注册机,则要读懂RealKeyCode = f(owner name/email)这段代码。
如何快速找到注册码判断的入口点呢,这就要借助上面提及的工具了,很明显的标志是字符串“注册成功”与“注册失败”,当然在实际中提示是不完全相同的。如果提示信息以资源的形式保存,则要使用ResHacker查看;否则就需要反汇编程序。
用IDA Pro反汇编时,在反汇编过程中有一个System DLL Directory要输入路径,最好将pocket pc \windows目录下的dll复制到一个文件夹(不是所有的都能复制),如C:\WINDOWS\CE。这些动态库可以是x86模拟器的,因为IDA只是关心他们的引出函数。
找到提示信息后,一般很快能找出注册码比较点。
拿ProWord为例,在ResHacker中查看字符串资源,并没有发现相关注册成功失败的信息,在对话框资源142中可以看出需要输入User name和unlock code。用Ida反汇编,在String窗口中可以发现:
.data:00020CF4 00000044 unicode Thank you for registering ProWord
.data:00020D38 00000030 unicode Not a valid Unlock code
顺着串往上找,发现:
.text:000178A0 BL sub_197C4 ;返回R0 == 0则注册码错误
.text:000178A4 MOVS R3, R0
.text:000178A8 BEQ loc_178D8
.text:000178AC CMP R4, #0
.text:000178B0 MOV R0, #0
.text:000178B4 LDRNE R0, [R4,#0x20]
.text:000178B8 BL sub_191D8
.text:000178BC MOV R3, #1
.text:000178C0 MOV R0, R4
.text:000178C4 STR R3, [R4,#0x7C]
.text:000178C8 BL mfcce300_1969
.text:000178CC LDR R0, =aThankYouForReg
.text:000178D0 B loc_178E8
.text:000178D4 off_178D4 DCD aThankYouForReg ; DATA XREF: sub_17858+74 r
.text:000178D4 ; "Thank you for registering ProWord"
.text:000178D8 loc_178D8 ; CODE XREF: sub_17858+50 j
.text:000178D8 LDR R0, =aNotAValidUnloc
.text:000178DC B loc_178E8
.text:000178E0 off_178E0 DCD aNotAValidUnloc ; DATA XREF: sub_17858+80 r
.text:000178E0 ; "Not a valid Unlock code"
sub_197C4是重点,进入看看,发现调用sub_19540,返回R0==0则注册码错,而且sub_19540有两个地方调用,一个是启动程序时验证注册码,一个是输入注册码时验证,因此要进入sub_19540修改返回值,如果在sub_19540外修改,则需要修改两次,如有遗漏,有时输入注册码虽然提示正确,但重新启动程序时会再次提醒非注册版本,这种错误经常出现!
有的程序提示信息以串资源的形式保存,如:
STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
2202, "Enter Code"
2203, "Thank you for registering. \nNow you need to restart game to apply changes."
}
应用程序要显示字符串,首先要载入该串资源,用API则调用如下功能:
int LoadString(HINSTANCE hInstance, UINT uID,
LPTSTR lpBuffer, int cchBufferMax);
在ARM中函数调用参数传递约定:
func(R0,R1,R2,R3,SP,SP+4,…,SP+4*n),返回值在R0中。
上例中uID = 2203 = 0x89D,在反汇编代码中应该有如下类似代码:
MOV R1, #0x890 ;;
-------------------------
不是MOV R1, #0x89D的原因
arm在32bit模式下,一条指令长度为4字节
mov指令的操作数2(op2)占12位
一种情况是:
11--------8--7------------------0bit
-------------------------------------
|#循环移位|-----8位立即数-----|
-------------------------------------
当操作数大于255时,就需要通过移位操作来构成
-------------------------
ORR R1, R1, #0xD
如何快速找到上述代码呢?可以在IDA中先生成.asm文件,File->Produce->Create ASM File。用Emeditor或其他可以用正则表示式查找功能的编辑器打开,查找MOV.*R.*#0x890,很快就能够发现。如果不太明白正则表示式,直接搜索#0x890也可,就是找到结果太多!
如果串资源是53569,”xxxxxxxx” 53679 = 0xD597,一时不明白MOV R1, #0x???,
就可以查找MOV.*R.*#0xD\d\d\d,找到后再缩小范围。
2. 将owner name或email和输入的注册码分别运算得到中间值,比较二者
imdKeyCode = f(owner name/email);
imdKey1Code = g(inputKeyCode);
if(imdKeyCode == imdKey1Code)
“注册成功”
else
“注册失败”
这种方法,不像方式1,并不将真正的注册码计算出来。
3. 有些程序只需要输入注册码,如isilo,此时的验证方式是看输入的注册码是否满足某些条件,例如运算后某些位是否为指定的值。
在实际程序中,验证注册码不一定只是比较一次,很多程序并不是立即判断输入注册码的正确与否,所以要具体对待。
以上是注册码验证的比较常见的方式。
四. 用EVC动态调试程序
在静态分析出现困难时,可以使用EVC动态调试待破解程序。
EVC菜单 File -> Open Workspace -> 文件类型选.exe ->打开,然后再Project ->Setting中设置download路径,将计算机与你的pocket pc连上,在EVC中选择POCKET PC 2002/2003 DEVICE,设置断点,Build -> Start Debug -> Go,然后操作你的Pocket pc,满足断点条件时,程序终止,这是可以调试程序了。
用vs.net2005调试ce软件
目前的方法不算是很好,暂时没有更好的,谁知道更好的方法,还请不要吝惜。
1,运行vs.net 2005, 菜单“工具”->“连接到设备”,选择合适的平台;
2,运行需要调试的目标程序;
3,菜单“工具”->“附加到进程”,传输(P):选择“智能设备”,限定符(Q):选择合适的平台;
附加到选择“本机(智能设备)代码”;
在可用进程中选择代调试的进程;
这时就可以调试该程序了。
用这种方法可以直接看到注册码验证方式1中的注册码。
如:
.text:0009D434 ADD R1, R6, #0x84
.text:0009D438 ADD R0, SP, #0x90
.text:0009D43C BL wcscmp ; 注册码比较
那么在内存单元中查看R0,R1所显示的内容,就可以知道正确的注册码了。
如何破解Pocket PC (for ARM)软件【5】
五 实例
1.TrueFax (Windows Mobile 2003 Phone Edition v2.05 (PXA-CPU))
http://www.ksesoftware.com/showarticle.php...9&sub=downloads
用ResHacker 依次打开TF20PoomDll.dll,Truefax.exe,TruefaxLangComp20.dll
在TruefaxLangComp20.dll中发现:
STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
300, "The entered name is too short."
301, "The reg.-no. does not fit with the user-name."
302, "This version was registered successfully. Thank you for your interest in %s."
303, "This trial version has expired!\nPlease register KSE Truefax."
}
反汇编Truefax.exe生成.asm文件,用正则表达式查找MOV.*R.*#0x12C
.text:00023A24 BL sub_1C294
.text:00023A28 MOV R4, R0
.text:00023A2C MOV R0, #0x12C
.text:00023A30 ORR R0, R0, #2 ;"302, "This version was regist..."
.text:00023A34 BL sub_20870
.text:00023A38 MOV R1, R0
.text:00023A3C MOV R2, R4
.text:00023A40 ADD R0, SP, #0xD0
.text:00023A44 BL wsprintfW
往上查找
.text:000239C8 ADD R1, SP, #0x10
.text:000239CC ADD R0, SP, #0x48
.text:000239D0 BL sub_234D4
.text:000239D4 CMP R0, #0
.text:000239D8 BEQ loc_23AB0 ;loc_23AB0 注册失败
.text:000239DC LDR R5, =unk_78418 ;注册正确
.text:000239E0 ADD R0, SP, #0x48
sub_234D4有两处调用,一次是输入注册码时验证,一次是启动时验证,修改sub_234D4返回值就可以了
sub_234D4
........
.text:00023590 loc_23590 ; CODE XREF: sub_234D4+A4j
.text:00023590 MOV R0, R7 ;改MOV R0, #1
.text:00023594 ADD SP, SP, #0x50
.text:00023598 LDMFD SP!, {R4-R7,PC}
2.找出TrueFax (Windows Mobile 2003 Phone Edition v2.05 注册码
注册码比较方式 f(name) == g(code),需要找出g(code)的逆变换
.text:0002351C MOV R1, R0 ; name
.text:00023520 STR R3, [SP,#8]
.text:00023524 MOV R5, #0
.text:00023528 MOV R6, #0
.text:0002352C STR R5, [SP,#0xC]
.text:00023530 MOV R2, #0
.text:00023534 STR R6, [SP,#0x10]
.text:00023538 ADD R0, SP, #0x28
.text:0002353C MOV R7, #0
.text:00023540 BL sub_230AC ; 变换name -> SP + 0x28 (15位)
.text:00023544 MOV R1, R4
.text:00023548 ADD R0, SP, #0
.text:0002354C BL sub_23280 ; 变换input_regcode ->SP (15位)
.text:00023550 MOV R3, R7
.text:00023554
.text:00023554 loc_23554 ; CODE XREF: sub_234D4+ACj
.text:00023554 ADD R0, SP, #0
.text:00023558 LDRH R0, [R3,R0]
.text:0002355C MOV R1, R0,LSL#16
.text:00023560 ADD R0, SP, #0x28
.text:00023564 LDRH R0, [R3,R0]
.text:00023568 MOV R2, R1,LSR#16
.text:0002356C ADD R3, R3, #2
.text:00023570 MOV R1, R0,LSL#16
.text:00023574 CMP R2, R1,LSR#16 ;比较name和reg.no变换后的结果
.text:00023578 BNE loc_23590 ;错误
.text:0002357C CMP R2, #0
.text:00023580 BNE loc_23554
.text:00023584 MOV R0, #1 ;正确
看sub_23280
.text:00023280 sub_23280 ; CODE XREF: sub_234D4+78p
.text:00023280 STMFD SP!, {R4-R6,LR} ;
.text:00023284 SUB SP, SP, #0x30
.text:00023288 MOV R6, R0
.text:0002328C MOV R5, R1
.text:00023290 SUB R3, R5, #2
.text:00023294
.text:00023294 loc_23294 ; CODE XREF: sub_23280+20j
.text:00023294 LDRH R0, [R3,#2]!
.text:00023298 MOV R1, R0,LSL#16
.text:0002329C MOVS R2, R1,LSR#16
.text:000232A0 BNE loc_23294
.text:000232A4 SUB R0, R3, R5
.text:000232A8 MOV R1, R0,LSR#1
.text:000232AC CMP R1, #0xF ;长度判断 应该为15位
.text:000232B0 BNE loc_232F8
.text:000232B4 ADD R0, SP, #0x10
.text:000232B8 ADD R4, SP, #0x10
.text:000232BC SUB R3, R5, R0
.text:000232C0
.text:000232C0 loc_232C0 ; CODE XREF: sub_23280+50j
.text:000232C0 LDRH R2, [R4,R3]
.text:000232C4 MOV R0, R2,LSL#16
.text:000232C8 STRH R2, [R4],#2
.text:000232CC MOVS R1, R0,LSR#16
.text:000232D0 BNE loc_232C0
.text:000232D4 ADD R1, SP, #0x10
.text:000232D8 ADD R0, SP, #0
.text:000232DC BL sub_22DF0 ;去掉第1,3,5,7位
.text:000232E0 ADD R0, SP, #0
.text:000232E4 BL sub_22EA0
.text:000232E8 ADD R0, SP, #0
.text:000232EC BL sub_22AD8 ;1,3,5,7位是否为0 2 7 4
.text:000232F0 CMP R0, #0
.text:000232F4 BPL loc_23304 ; 是
.text:000232F8
.text:000232F8 loc_232F8 ; CODE XREF: sub_23280+30j
.text:000232F8 MOV R0, #0 ;返回错
.text:000232FC ADD SP, SP, #0x30
.text:00023300 LDMFD SP!, {R4-R6,PC}
.text:00023304 ; ----------------------------------------------------------------------------------------------
.text:00023304
.text:00023304 loc_23304 ; CODE XREF: sub_23280+74j
.text:00023304 MOV R1, R0
.text:00023308 ADD R0, SP, #0x10
.text:0002330C BL sub_231B0 ;变换.text:00023310 ADD R1, SP, #0
.text:00023314 ADD R0, SP, #0x10
.text:00023318 BL sub_22D44
.text:0002331C ADD R0, SP, #0x10
.text:00023320 SUB R3, R0, R6
.text:00023324
.text:00023324 loc_23324 ; CODE XREF: sub_23280+B4j
.text:00023324 LDRH R2, [R6,R3]
.text:00023328 MOV R0, R2,LSL#16
.text:0002332C STRH R2, [R6],#2
.text:00023330 MOVS R1, R0,LSR#16
.text:00023334 BNE loc_23324
.text:00023338 MOV R0, #1
.text:0002333C ADD SP, SP, #0x30
.text:00023340 LDMFD SP!, {R4-R6,PC}
sub_231B0
.text:000231B0 sub_231B0 ; CODE XREF: sub_23280+8Cp
.text:000231B0 STMFD SP!, {R4-R11,LR}
.text:000231B4 SUB SP, SP, #0x18
.text:000231B8 MOV R10, R0
.text:000231BC MOV R2, R1
.text:000231C0 LDR R1, =aTruefax2_0Phon
.text:000231C4 MOV R3, #0x194
.text:000231C8 MLA R5, R2, R3, R1
.text:000231CC MLA R0, R2, R3, R1
.text:000231D0 ADD R9, SP, #0
.text:000231D4 MOV R8, #0xB
.text:000231D8 MOV R7, R5
.text:000231DC LDR R4, [R0,#0x16C]; 1 5 0 2 6 3 4 7 8 9
.text:000231E0 MOV R6, R5
.text:000231E4 MOV R11, #0
.text:000231E8
.text:000231E8 loc_231E8 ; CODE XREF: sub_231B0+A0j
.text:000231E8 LDR R0, [R6,#0xC8];A 5 3 6 2 9 7 8 1 0 4
.text:000231EC MOV R3, R11
.text:000231F0 ADD R1, R10, R0,LSL#1
.text:000231F4 LDRH R2, [R1]
.text:000231F8 MOV R0, R2,LSL#16
.text:000231FC MOV R1, R0,LSR#16
.text:00023200 SUB R2, R1, #0x30
.text:00023204 CMP R2, R4
.text:00023208 BEQ loc_23224
.text:0002320C MOV R1, R5
.text:00023210
.text:00023210 loc_23210 ; CODE XREF: sub_231B0+70j
.text:00023210 ADD R1, R1, #4
.text:00023214 LDR R0, [R1,#0x16C] ; 1 5 0 2 6 3 4 7 8 9
.text:00023218 ADD R3, R3, #1
.text:0002321C CMP R2, R0
.text:00023220 BNE loc_23210
.text:00023224
.text:00023224 loc_23224 ; CODE XREF: sub_231B0+58j
.text:00023224 LDR R0, [R7,#0x11C] ;3 6 1 2 2 5 8 3 7 4 4
.text:00023228 SUB R8, R8, #1
.text:0002322C ADD R7, R7, #4
.text:00023230 SUBS R1, R3, R0
.text:00023234 ADDMI R1, R1, #0xA ; 负号
.text:00023238 ADD R0, R1, #0x30
.text:0002323C MOV R1, R0,LSL#16
.text:00023240 MOV R2, R1,LSR#16
.text:00023244 STRH R2, [R9],#2
.text:00023248 SUB R6, R6, #4
.text:0002324C CMP R8, #0
.text:00023250 BHI loc_231E8
.text:00023254 ADD R0, SP, #0
.text:00023258 STRH R11, [SP,#0x16]
.text:0002325C SUB R3, R0, R10
.text:00023260
.text:00023260 loc_23260 ; CODE XREF: sub_231B0+C0j
.text:00023260 LDRH R2, [R10,R3]
.text:00023264 MOV R0, R2,LSL#16
.text:00023268 STRH R2, [R10],#2
.text:0002326C MOVS R1, R0,LSR#16
.text:00023270 BNE loc_23260
.text:00023274 ADD SP, SP, #0x18
.text:00023278 LDMFD SP!, {R4-R11,PC}
.text:00023278 ; End of function sub_231B0
sub_231B0功能:
按位置A 5 3 6 2 9 7 8 1 0 4取数
数在1 5 0 2 6 3 4 7 8 9 中位置
减去3 6 1 2 2 5 8 3 7 4 4 小于0加上A
u8 pos[] = {1,5,0,2,6,3,4,7,8,9};
u8 sub[] = {3,6,1,2,2,5,8,3,7,4,4};
//u8 key_pos[] = {0xa,5 ,3,6,2,9,7,8,1,0,4};
u8 key_pos[] = {14,9,6,10,4,13,11,12,2,0,8};
u8 code[15];
//f(L"wh_cxh") = "048762306414292"
num[] = {0,8,6,3,6,4,1,4,2,9,2};
for(int i = 0; i 9)
temp -= 0xa;
code[key_pos] = pos[temp];
}
code[1] = 0;
code[3] = 2;
code[5] = 7;
code[7] = 4;
for(int j = 0; j < 15; j++)
printf("%x", code[j]);
//209287744639792
name : wh_cxh
regcode : 209287744639792
发表评论
-
CUBRID 中的线程模型
2012-01-20 10:32 832CUBRID 中的线程模型 2010 ... -
OpenNMS扩展 - 事件配置
2012-01-20 10:32 903OpenNMS扩展 - 事件配置 2011年04月24日 ... -
Process and Thread
2012-01-20 10:32 679Process and Thread 2011年02 ... -
转:构建可扩展的Java EE应用
2012-01-20 10:32 615转:构建可扩展的Java EE ... -
由C++转向C#需要注意的问题 (3)
2012-01-20 10:32 612由C++转向C#需要注意的问题 (3) 2010年06月02 ... -
vim配置
2012-01-19 15:32 960vim配置 2011年08月17日 1、编辑用户目录下的 ... -
python 常用类库!(转)
2012-01-19 15:32 1035python 常用类库!(转) 2011年01月21日 ... -
转:湘鄂情模式二
2012-01-19 15:32 537转:湘鄂情模式二 2011年08月10日 以人为本,建立 ... -
管理篇
2012-01-19 15:32 632管理篇 2011年01月23日 ... -
perfHUD使用说明
2012-01-19 15:32 728perfHUD使用说明 2011年04月14日 perf ... -
收拾包袱,收拾心情
2012-01-17 05:19 784收拾包袱,收拾心情 8小时前 枝鸦的枯叫,鸣醒了沉睡的 ... -
今天一说
2012-01-17 05:19 772今天一说 8小时前 本来早上是要六点起的,闹铃一 ... -
真的累了!对自己说声再见
2012-01-17 05:19 634真的累了!对自己说声再见 8小时前 这个冬天格外的寒冷, ... -
阿莫西林复方制剂
2012-01-17 05:19 1679阿莫西林复方制剂 8小 ... -
也许,再这样下去,我的心会开始为另一个他而心跳
2012-01-17 05:19 672也许,再这样下去,我的 ... -
注册必备……
2012-01-16 04:13 1122注册必备…… 2010年07 ... -
Windows下的Qt环境安装
2012-01-16 04:13 2420Windows下的Qt环境安装 20 ... -
Visual Studio (Team Suite and Professional) 2005&2008 微软官方下载
2012-01-16 04:13 1097Visual Studio (Team Suite and P ...
相关推荐
wince设备使用sqlite数据库必备资源,需要 .NET Compact Framework 3.5,基于sqlite3;如果你的项目基于 .NET Compact Framework 2.0,请下载我另一个资源1.0.66版本。
totalcross fo rPocketPC with ARM cpu
Often Pocket PC programs need a background process and most of existing Pocket PC programs implement it by creating an executable file which is started during system start-up. But Pocket PC has 32 ...
This book is both a tutorial and reference guide for writing network applications on Pocket PC 2002 and Pocket PC Phone Edition devices. The term network application does not limit the scope of this ...
Google Map for Pocket PC,本文件为CAB安装包,直接拷贝到Pocket PC上然后运行就可以了。
VS2008 Pocket PC 2003 SE仿真程序上网设置
被文档介绍了在VS2005+ActiveSync+PPC环境下如何正确配置使模拟器Pocket PC上网的说明。
安裝方法: 1. 安裝evb runtime ... 把下載的文件Copy 入Pocket pc 內執行 2. 解壓estock.zip ...首先把Pocket pc 連接PC , 並且可以上Internet 使用 資料下載 其後 可以使用 圖表 及 分析.
文档明确描述如何使用非 Microsoft 基础类 MFC Win 32 应用程序中 SHFullScreen API 来创建 PocketPC 上全屏窗口。 但是, 文档未介绍相同过程基于 MFC 的应用程序。 本文介绍如何通过使用 Win32API 或 MFC 进行全 ...
本软件是基于Pocket PC、手持设备和手机上的掌上水准测量程序,解决外业水准测量的记录问题,程序能根据观测等级、仪器类型按规范要求的观测顺序自动移动光标位置,自动完成计算并根据各限差要求对超限数据提醒;...
这是一个基于WinCE Pocket PC,用C#开发出来的手机小游戏,占用空间下,可供休闲娱乐
XChange是一款运行于Pocket PC的货币兑换软件,本软件为CAB安装包。需要.netFramework的支持。
飞鸽传书for pocketpc pda版本。可与PC通讯
实战Pocket PC程序设计 详解介绍了 Pocket PC程序设计的主要方面,适合熟悉桌面开发,想进行 Pocket PC手机程序设计的入门者了解PocketPC 开发与桌面的主要不同,这个是中文版
简单易懂轻松用c#语言中实现 pad 或pocket pc 的键盘的隐藏和显示
Pocket PC 2003 PDA简易通讯录用VS2008 c#语言做 符合团队开发标准
Pocket PC 充电监视器 (Pocket PC 掌上助手)是针对Pocket PC开发的一款免费的电池监视软件,在使用 ActiveSync 连接掌上设备时,可以自动检测出电源电量,充电状态并直接在Windows状态栏中显示。
基于PocketPC的汉字输入系统的设计与实现 对设计输入法有一定的理论指导作用。
pocket pc for windows mobile 6专用超频软件,可以设置程序使用频率....
此软件适用于wm5 wm6部分机型请自测。特别申。明版权归原作者所以,本人只是分享软件。