BePlan 1.21 Introduction BePlan is a commercial app from ABISOFT : "BePlan is a calendar and datebook for the BeOS that synchronizes with Palm Computing connected organizers." (as stated in the doc) Damn..don't have Palm :) Anyway it comes as a fully functionnal demo for 1 month, with nag screen and stuff. There's probably a way to register (a quick scan of the exe with diskprobe shows a lovely license,try offset bb0c0) but this essays doesn't cover it. Tools Required Your favourite text editor (as usual) I use StyledEdit dasm, the Linux disassembler by SiuL+Hacky Your favourite HEX editor (as usual) I use bvi db, the BEOS debugger What's different? The app is commercial, this means there's no "standard" way of registering it.No regcode to enter.So it's about datecheck for the demo,and nag box removal. Some quick notes on the debugger: db is launched from the command line,i.e open up a terminal and type : > db BePlan A box comes with 2 buttons : "OK" and "Details" telling you BePlan has "encountered an error". In fact the OS is forcing an error in order to launch the debugger. Click "Details", then another box comes up with details on the thread. Click "debugger" then another term window opens up with a prompt like (with BePlan): loading symbols fc201cac: * 18c483 addl $0x18, %esp BePlan: now you're in the debugger,starting on the stack. A recent article in the Be Newsletter talked about the way memory is handled by the debugger: (Volume 3,Issue 47) [....] 0x00000000 - kernel 0x80000000 - application code heap follows code 0xea000000 - addons 0xec000000 - libraries 0xfc000000 - stack In addition, you might have: 0xd0000000 - app_server shared data 0xa0000000 - net_server shared data [...] Here are a few interesting commands when in the debugger: first,how to get help: type "help" or "h". Interesting stuff for us is: "l": il addr count list instructions. Addr defaults to pc. (count is in hex) l addr count (same as 'il') >> list instructions,might be useful. >> A star (*) marks where you are. "s","so","g" and "exit": s step one instruction >> single-stepping so step one instruction, step over calls >> same but doesnt go into stuff "called",i.e : >> "+0005 ec073341: 00000000e8 call 0xec073346 " >>so you won't go in 0xec073346 (the code will be executed anyway). >> you'll go the next instruction after ec073341, which is ec073346. g go >> launch the program from where you are, and stop when needed >> (i.e: if any breakpoints are set) exit exit (kill this team - risky, if in awkward state) >> this just closes the db window "br" and "cab": br [addr [condition]] set [conditional] breakpoint. Omit addr to list all breaks. >> basic cab clears all breakpoints >> basic Now you sdhould say: okay,but..how do I set breakpoints? Well, the big stuff comes from : "sd": sd prefix display symbols that match prefix >> this is what you call when you wanna find something like : >> what's the address for the call to the "time" function ? >> answer : type "sd time" So..that's the commands we'll use to get what we want. First thing, find the time function, because we are almost sure that the app goes like this: ...start ...call the time function from a library ..get the result and compare it ...go on if it's less than one month So: ...call the time function from a library now just type "sd time" in the debugger: BePlan:sd time ec516000 text time ec07333c text time >>first call ec055ca8 text timelocal ec150458 text Timeout__C8BInvoker ec086fa4 text times ec0a6570 data timezone BePlan: We have 2 calls to the "time"' function. Let's set breakpoints on it: BePlan:br ec516000 BePlan:br ec07333c >>break on 1st call BePlan:br >>list the break ec07333c BePlan: Now just type "g" to launch the app: BePlan:g time: time: +0000 ec07333c: * 55 pushl %ebp BePlan: So we stopped on the first call to "time". Note that we're in a library (ecxxxxxx), not in the app. (the app would show an address like 800xxxxx) Now we must step until we get back on the app code, where we should find a test to compare if the date is one month different. Use the "so" command to step forward until we get back to the app code (offset 800xxxxx). Type "so" then stick on the return key (return repeat the last command in the debugger) until you see 800xxxxx code: time: +0027 ec073363: * c3 retn >> end of the function;return to the main code BePlan: 80040f13: * 04c483 addl $0x04, %esp >> first next app instruction It's time to look now for the test on the time function result (compare current time with recorded time). Might be useful to have the disassembly. Run dasm. Once you get the file, open it and search offset 40f13: 0x00040f13 add $0x4,%esp We're looking for a test on a date,so it could be : jump if less than equal,no? Search for the next "jle": 0x0004137a jle 0x00041383 We suppose the app get the value from the "time" function, and then compare it with the time stored somewhere in the preferences of the app. Then it jumps if the time is less or equal to 1 month. Patching it to a jump, so the app "thinks" it's always OK: Open up HEX editor (here bvi): g 4137a r EB (Esc) : wq! Now set up your date to a few months later, launch BePlan: that's it ! no more expiration date test heh. But there's still a box telling you it's a demo version... Well, back to db. Relaunch a debugger session on BePlan and set a breakpoint on the "jump if less than equal" we seen before: loading symbols fc201cac: * 18c483 addl $0x18, %esp BePlan:br 8004137a BePlan:g 8004137a: * 077e jle 0x80041383 BePlan:l 8004137a: * 077e jle 0x80041383 8004137c: 010000011787c6 movb $0x01, 0x00000117(%edi) 80041383: 0000000117bf80 cmpb $0x00, 0x00000117(%edi) 8004138a: 00000111840f jz 0x800414a1 80041390: 000001b068 pushl $0x000001b0 From here we we gonna "step over calls" to the call of the first nag: type "so" and stick on the return key until you get the first screen with the eyes moving. here it is: BePlan: 8004206d: * d1ff call %ecx BePlan: 8004206f: * 04c483 addl $0x04, %esp BePlan: 4206d is the call to the first nag screen : NOP it!! with bvi: ("R" for replace several bytes,different from "r") g 4206d R 9090 (Esc) : wq! Relaunch BePlan : damn,nag box again. This time it's an "alert" box, so we gonna catch the "alert" call within the debugger. Start a db session, set a breakpoint on 8004206d (first nag "noped"), and then scan code for alert calls (sd command). Then put a breakpoint on it: loading symbols fc201cac: * 18c483 addl $0x18, %esp BePlan:br 8004206d BePlan:sd alert ec165a74 text AlertPosition__6BAlertff BePlan:br ec165a74 BePlan: Type "g" to go til 1st breakpoint (which is first nag "noped"): BePlan:g 8004206d: * 90 nop BePlan:l 8004206d: * 90 nop 8004206e: 90 nop 8004206f: 04c483 addl $0x04, %esp 80042072: 0000000117bf80 cmpb $0x00, 0x00000117(%edi) 80042079: 1574 jz 0x80042090 BePlan: Retype go to go til the "alert" call: BePlan:g BAlert::AlertPosition: AlertPosition__6BAlertff: +0000 ec165a74: * 55 pushl %ebp BePlan: Now type "so" and stick return key til you have the second nag on screen, they click "OK": BePlan: 80026c69: * fffff2d6e8 call 0x80025f44 BePlan: 80026c6e: * 04c483 addl $0x04, %esp BePlan: From 26c69 to 26c6e is the call to the second nag. noping (with bvi) : g 26c69 R 9090909090 (Esc) : wq! Relaunch BePlan.....arggghhhhhhhh Another one,this time it's Net+. Same stuff: db session,with brekpoint on last nag: loading symbols fc201cac: * 18c483 addl $0x18, %esp BePlan:br 80026c69 BePlan:g 80026c69: * 90 nop BePlan:l 80026c69: * 90 nop 80026c6a: 90 nop 80026c6b: 90 nop 80026c6c: 90 nop 80026c6d: 90 nop BePlan: "so" and stick on return key til Net+ nag: BePlan: 80026cc7: * ffffdb98e8 call 0x80024864 BePlan: 80026ccc: * 04c483 addl $0x04, %esp BePlan: Here's the call : 80026cc7 (yeah the last one :) ) noping.. g 26cc7 R 9090909090 (Esc) : wq! Relaunch BePlan: made it! No more nag boxes. Conclusion That's the first essay dealing with "db" : the Be debugger.