IPB

Welcome Guest ( Log In | Register )

2 Pages  1 2 > 
Reply to this topicStart new topicStart Poll

Outline · [ Standard ] · Linear+

> Linux disassembler, Tool used to crack firmware

Lex
post Sep 22 2004, 01:50 PM
Post #1


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



My status:

using s10sh I got the relevant files out the camera.
I tried objdump on camera.exe, but the binary format is not compatiible with any of the targets.

Therefore, I started by own disassembler.
It can disassemble fully automatically 3/4 of camera.exe now.
I use heuristics to find strings, and follow jumps and calls.

A problem is indirect jumps.
Does anybody know what lcalll *0x1234 exactly does?
I gues it jumps far to the address stored at memory localtion 0x1234 in some data segment. But what is the base of that data segment?

I intend to add interactivity, to allow manually adding more entry points.
Then I'll disassemble both B7.1 and Canon's original firmware to compare.

I am willing to share my source if there is interest.
Not the disassembled code for legal reasons.
Maybe we need to set up a source forge server or CVS repository.

Anyone with expereience on that?
We also need to figure out whether to develop under Linux or Windows.
My preference is Linux.

Lex

Download LDA source here - admin
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 1 2004, 02:19 PM
Post #2


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 1 2004, 02:23 PM)
Lex,
It compiles fine under cygwin with no modifications, besides makefile.  But there are link problems.  Can you give me a hint where should I look for the missing libs on Unix?  What is the name of package/library?  Cygwin should be almost a replica of what they have on unix.

*



You miss the binutils package.
You can download the source package

binutils-2.13.90-20030111-1-src.tar.gz

from

http://sourceforge.net/project/showfiles.php?group_id=2435

You need to enable all targets of binutils. See my README file for this.
Next you need to build binutils as described in that package.
When that is done, you need to edit my makefile to fill in the path to binutils.

Good luck!

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 2 2004, 02:13 AM
Post #3


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



Lex, you are right. It wasn't built. I don't know unix environment well enoug. So I need some help here. How do I "enable all targets"? It looks like by default it builds for the machine you are running on. And readme doesn't say much about it.
QUOTE
    README for GNU development tools

This directory contains various GNU compilers, assemblers, linkers,
debuggers, etc., plus their support routines, definitions, and documentation.

If you are receiving this as part of a GDB release, see the file gdb/README.
If with a binutils release, see binutils/README;  if with a libg++ release,
see libg++/README, etc.  That'll give you info about this
package -- supported targets, how to use it, how to report bugs, etc.

It is now possible to automatically configure and build a variety of
tools with one command.  To build all of the tools contained herein,
run the ``configure'' script here, e.g.:

./configure
make

To install them (by default in /usr/local/bin, /usr/local/lib, etc),
then do:
make install

(If the configure script can't determine your type of computer, give it
the name as an argument, for instance ``./configure sun4''.  You can
use the script ``config.sub'' to test whether a name is recognized; if
it is, config.sub translates it to a triplet specifying CPU, vendor,
and OS.)

If you have more than one compiler on your system, it is often best to
explicitly set CC in the environment before running configure, and to
also set CC when running make.  For example (assuming sh/bash/ksh):

CC=gcc ./configure
make

A similar example using csh:

setenv CC gcc
./configure
make

Much of the code and documentation enclosed is copyright by
the Free Software Foundation, Inc.  See the file COPYING or
COPYING.LIB in the various directories, for a description of the
GNU General Public License terms under which you can copy the files.

REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info
on where and how to report problems.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 2 2004, 07:48 AM
Post #4


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 2 2004, 10:13 AM)
Lex, you are right.  It wasn't built.  I don't know unix environment well enoug.  So I need some help here.  How do I "enable all targets"?  It looks like by default it builds for the machine you are running on.  And readme doesn't say much about it.
*



Indeed it builds by default for the host.

You should edit the file bfd/configure in the binutils directory.
In that file, there should be a variable named all_targets.
You should change the assignment of it from false to true.

Next you build binutils as described in its README.
This should just consist of

./configure
make

Then proceed as my README tells you.

Cheers,

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 3 2004, 11:18 AM
Post #5


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 3 2004, 04:42 PM)
Lex, I finally managed to build lda.  Didn't try to disassemble anything yet, though.
*



Great!
Just run it now. It is amazingly fast. Needs about a second to decode the firmware.

I am updating the disassembler to include the decoding of the RXE format, as posted by Vadikas.
It can now decode the header automatically, so no need to pass the load address any more.

I am also working on the fix-up code. In order to allow relocation of data at load time, while the code is in ROM (or Flash?), they replace access through a data segment pointer by interrupts that load the data segement pointer from a table. These interrupts appear as 'int 0x90' instructions. They have an extra argument though (or even more), that derails the disassembly process.
I should be able to fix this given the RXE documentation.

Next is line is detection of jump tables that got generated for switch statements.
This will substantially reduce the size of the entrypoint file and increase the precision of the disassembly process.

Also on the list is to add a file with comment per address. That would allow us to annotate the code by mixing the comment with the disassembly. Several people can then add their findings and in this way create a knowledge base.

A nice thing about your own disassembler is that you can extend it when you need additional features. cool.gif

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 3 2004, 07:55 PM
Post #6


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



QUOTE(Lex @ Oct 3 2004, 01:18 PM)
Great!
Just run it now. It is amazingly fast. Needs about a second to decode the  firmware.

The only problem is that I don't have anything to test it with yet smile.gif Is there a way to break apart FIR file? I don't have Linux, so I can't use s10sh.

Important thing it that lda builds on PC and if someone else would want to try it, I can provide Windows executable.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 4 2004, 01:34 AM
Post #7


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



Lex,

LDA seems to be working fine under windows command prompt. All you need is cygwin1.dll in the path. Cygwin doesn't have to be installed. Should I upload binary, so others can play with it or should I wait for future updates?
--
Steve
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 6 2004, 12:14 AM
Post #8


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



Lex, can you explain what -l option in lda means? Actually how, when I started playing with diassembly, I have some questions. First I simply opened the file using DOS DEBUG. And the main entry point is indicated at offset of 0x36 and whatever CS value is. CS value, of course, is relative. EXE is relocatable file and initial CS value is defined by the loader as well as all segment operands for long jumps. When I looked at hex dump I found that this entry point is at offset 0x5F226 from the beginning of the file. So I am curious how do you deal with all this.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 6 2004, 02:54 PM
Post #9


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 6 2004, 08:14 AM)
Lex, can you explain what -l option in lda means?  Actually how, when I started playing with diassembly, I have some questions.  First I simply opened the file using DOS DEBUG.  And the main entry point is indicated at offset of 0x36 and whatever CS value is.  CS value, of course, is relative.  EXE is relocatable file and initial CS value is defined by the loader as well as all segment operands for long jumps.  When I looked at hex dump I found that this entry point is at offset 0x5F226 from the beginning of the file.  So I am curious how do you deal with all this.
*



The load address was taken from Alex'wiki.
Later on I found out it is also in the file header. The file is not quite in .exe format though, it is in .rxe format.
That is, the .exe header points to a .rxe descriptor that holds the inital cs and offset.
I adjusted LDA to read this from file, so the new version with not have the -l switch any more.

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 6 2004, 05:27 PM
Post #10


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



And what about direct far pointers in general? In the instructions and in data area? In EXE format they are relocatable and adjusted by the loader. Should I assume that in this case, if loaded at coreect address, they are resolved properly?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 6 2004, 11:36 PM
Post #11


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 7 2004, 01:27 AM)
And what about direct far pointers in general?  In the instructions and in data area?  In EXE format they are relocatable and adjusted by the loader.  Should I assume that in this case, if loaded at coreect address, they are resolved properly?
*



I assume so too.
I think you should read rxe.pdf, which can be reached from the links section.

http://www.syeager.org/300d/forum/index.php?showtopic=14

This explains the relocation and load process for this embedded dos version.
We do not know though how the loader fills the relocation table. But as far as I can see, this only holds for data. Code should have been relocated by the rxe converter.
Following data though will be much harder.

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
pofig37
post Oct 11 2004, 12:46 PM
Post #12


Unregistered









Here's the script in the IDA scripting language that I have used to reverse RXE runtime fixups.
--Alex
CODE

static unRXE() {
 auto addr, fixup_id, opcode;  

 addr = 0x10000;
 do {
   if ((Byte(addr) == 0xCD) && (Byte(addr+1) == 0x90)) {
     fixup_id = Byte(addr+2) >> 5;
     if (fixup_id == 0) {
opcode = 0xB8;
     } else if (fixup_id == 1) {
opcode = 0xBB;
     } else if (fixup_id == 2) {
opcode = 0xB9;
     } else if (fixup_id == 3) {
opcode = 0xBA;
     } else if (fixup_id == 4) {
opcode = 0xBE;
     } else if (fixup_id == 5) {
opcode = 0xBF;
     } else if (fixup_id == 6) {
opcode = 0xBD;
     }
     if (fixup_id != 7) {
PatchByte(addr, opcode);
PatchWord(addr+1, 0x1021); // patch with DSEG
addr = addr + 2;
     }
   }
   addr = NextAddr(addr);
 } while (addr != 0xFFFFFFFFL);
}

QUOTE(Lex @ Oct 3 2004, 11:18 AM)
Great!
Just run it now. It is amazingly fast. Needs about a second to decode the  firmware.

I am updating the disassembler to include the decoding of the RXE format, as posted by Vadikas.
It can now decode the header automatically, so no need to pass the load address any more.

I am also working on the fix-up code. In order to allow relocation of data at load time, while the code is in ROM (or Flash?), they replace access through a data segment pointer by interrupts that load the data segement pointer from a table. These interrupts appear as 'int 0x90' instructions. They have an extra argument though (or even more), that derails the disassembly process.
I should be able to fix this given the RXE documentation.

Next is line is detection of jump tables that got generated for switch statements.
This will substantially reduce the size of the entrypoint file and increase the precision of the disassembly process.

Also on the list is to add a file with comment per address. That would allow us to annotate the code by mixing the comment with the disassembly. Several people can then add their findings and in this way create a knowledge base.

A nice thing about your own disassembler is that you can extend it when you need additional features.  cool.gif

Lex
*


Go to the top of the page
+Quote Post
Lex
post Oct 11 2004, 01:37 PM
Post #13


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(pofig37 @ Oct 11 2004, 08:46 PM)
Here's the script in the IDA scripting language that I have used to reverse RXE runtime fixups.
--Alex
*



Thanks Alex.
I was looking at this stuff too and worked it into LDA.
I wonder where you got the address of the data segment 0x1021 from?

I uploaded a new LDA to the ipload section.

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
pofig37
post Oct 11 2004, 02:55 PM
Post #14


Unregistered









The way I loaded file into IDA was to load it first as the regular EXE file. When IDA loads a file, it asks you where in memory would you like to locate it. By default it would be loaded at the segment 0x1000 and data segment created at the address 0x1021:0000. I would then load camera.exe as an additional binary file at 0x80A0 (or whatever it is).

-- Alex
QUOTE(Lex @ Oct 11 2004, 01:37 PM)
Thanks Alex.
I was looking at this stuff too and worked it into LDA.
I wonder where you got the address of the data segment 0x1021 from?

I uploaded a new LDA to the ipload section.

Lex
*


Go to the top of the page
+Quote Post
syeager
post Oct 11 2004, 09:29 PM
Post #15


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



Lex,

I uploaded Windows executable into Uploads. Seems to be working fine, but you can check my camera.dis to make sure (it's in private).

And I have a wish list:

1. Is it possible to make an assumption on the code/data segment values and display the addresses in SEG:OFFSET format, so you can follow long pointers?

2. Find call/jump/data targets in code and create some cross reference comments where it's referenced and where it's referenced from? Or even better, make a symbolic labels.

3. Display unrecognized areas in hex dump form, or use the assembler directive DB (define byte) for this?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 11 2004, 11:04 PM
Post #16


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 12 2004, 05:29 AM)
Lex,

I uploaded Windows executable into Uploads.  Seems to be working fine, but you can check my camera.dis to make sure (it's in private).

And I have a wish list:

1.  Is it possible to make an assumption on the code/data segment values and display the addresses in SEG:OFFSET format, so you can follow long pointers?

2.  Find call/jump/data targets in code and create some cross reference comments where it's referenced and where it's referenced from?  Or even better, make a symbolic labels.

3. Display unrecognized areas in hex dump form, or use the assembler directive DB (define byte) for this?
*



Steve,

I diffed my and your output and I see some annoyinging differences.
I expect these stem from different binutils versions.
To give an example:

Mine
< 0x8d109 T----- 0e pushw %cs
< 0x8d10a T----- e8 28 56 call 0x92735

Yours
> 0x8d109 T----- 0e push %cs
> 0x8d10a T----- e8 28 56 call 0x00002735

Something seems to be wrong with the relative jumps at your side.
I guess the programm counter is not communicated in the right way to binutils.
This also produces the 'target address .... is too low' messages.
I also see that I get the movw, pushw, etc versions and you don't. What do you prefer?
What binutils version are you using? I use 2.9.1.

Reguarding your wishes:

1. For data accesses, this will be some work. I''ll look into it.
For %cs based addressing, this should be more easy.

2. I'll add cross-references and a mechanism to label addresses.
I'll probaby extend the the comments mechanism for that.

3. Good point, put on tthe list.

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 12 2004, 06:42 AM
Post #17


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



I will look into it, build with your version of binutils and sort it out.
It would be good if LDA would be independent of the binutils version.

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 12 2004, 08:36 PM
Post #18


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



Lex,

I updated LDA.EXE and camera.dis

BTW, how come I have things like PUSHW 100, etc. in decimal?

Also, I've been thinking about rewriting instruction set interpreter for LDA as you mentioned. Can you give me a pointer to binutils interface documentation? I don't think it will be too difficult to do. I used to disassemble 8080 and 8086 code by hand in old good times rolleyes.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Lex
post Oct 13 2004, 07:11 AM
Post #19


Advanced Member
***

Group: Admin
Posts: 188
Joined: 22-September 04
Member No.: 14



QUOTE(syeager @ Oct 13 2004, 04:36 AM)
Lex,

I updated LDA.EXE and camera.dis

BTW, how come I have things like PUSHW 100, etc. in decimal?

Also, I've been thinking about rewriting instruction set interpreter for LDA as you mentioned.  Can you give me a pointer to binutils interface documentation?  I don't think it will be too difficult to do.  I used to disassemble 8080 and 8086 code by hand in old good times  rolleyes.gif
*



Some immediates are now (binutils 2.15) in decimal, some are binary.
I do not know why. I had to adjust LDA to this.

You could look at opcodes/i386.c, I think. The whole processes is not very clear to me.
It's lots of tables and macros. Changing opcodes should be doable though.
You can also change LDA to call the _intel_syntax version of the disassemble function. It's called twice, once in text.c, once in switch.c.
As I said, it's buggy, in the sense that some instructions do not disassemble correctly. But maybe the syntax is more what you want and we can look into i.

Lex
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
syeager
post Oct 14 2004, 06:17 AM
Post #20


Advanced Member
***

Group: Admin
Posts: 311
Joined: 22-September 04
From: Edison, NJ USA
Member No.: 2



Lex,

Syntax will be important only if we will need to assemble it again at some point. In case of intel you can use many old tools available for PC to build DOS programs. But we can always use Lex to convert it. ... I am not talking talking about you here smile.gif

I looked at the source and so far I can't figure out how it works. I've been thinking about rewriting the interpreter alltogether. One benefit is that in this case I can get rid of Cygwin and perhaps even make some nice GUI frontend.

Is there ANY documentation at all describing disassembler API of binutils, besides the source code?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

2 Pages  1 2 >
Reply to this topicTopic OptionsStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:
 

Lo-Fi Version Time is now: 10th September 2010 - 01:20 PM

Enamel Art Studio

Stats