Anyone ever try to get the hex off of an arduino to be able to copy it to another one?? I lost the code and dont need it, but would like to copy the sketch to another arduino.
…sigh
Anyone ever try to get the hex off of an arduino to be able to copy it to another one?? I lost the code and dont need it, but would like to copy the sketch to another arduino.
…sigh
yup. You can simply use the avrdude from the command line - but you do need either an ICSP programmer, OR, Another Arduino running “MegaISP” sketch.
If you’ve never touched avrdude directly before - have a quick read of Ladyada’s tutorial http://www.ladyada.net/learn/avr/avrdude.html
Basically, some permutation of this command line will download the file:
avrdude -p m328 -P COM5 -c arduino -U flash:sketchname.bin:r
-p the chipname exactly as found in avrdude ( To get a list of partnames for -p ; run avrdude -c avrisp)
-P the programmers port (usb, COM1, etc)
-c the programmer type ‘usbtiny, arduino, avrisp, etc’
-U is the real guts of it. “flash:r” says ‘read the flash’. “:sketchname.bin” says write it out to that filename and the final “:r” tells avrdude to do it in Raw Binary format.
You will need to fiddle/tweak the above - but read the tutorial. If you dont have a programmer, read up on the MegaISP sketch (bundled in arduino, under Examples from memory…)
Note this ‘reads back’ the flash memory, meaning it will also pull in the bootloader. Re programming (using avrdude) will transfer the same bootloader onto the target board - so keep them in the same ‘family’ (i.e, dont try this moving an uno sketch to a mega… )
MegaISP Info: http://playground.arduino.cc/Code/MegaISP
If using an Uno or similiar to program; refer: http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection - but you need to read http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1295386772 where it will basically tell you to use the 10uf cap these days if the 120ohm dont work. This prevents the arduino resetting when avrdude opens the serial connection. Oh, and check the baudrates - older arduinos used weird 19200 settings, which if you dont use, will cause errors…
Ah k thanks! Good to know. Was kind of hoping to move the sketch from a teensy 3 to a uno. But sounds like a nogo. Ah well. Ill give it a read though.
Once you have the HEX code, you can use ReAVR to ‘reassemble’ the asm source file from the hex AVR binary.
http://www.avrfreaks.net/index.php?func=viewItem&item_id=272&module=Freaks%20Tools
Of course that will be in ASM, not C.
This is the Blink example sketch, reasassembled:
; reassembly of “Blink.cpp.hex”
; created by ReAVR V3.5.0
; at 2014/07/26 - 23:42:42
; for Atmel AVR assembler
;---------------------------------------
; AVR_TYPE=
; FLASH_SIZE=8KB
; SRAM_START=0x60
;---------------------------------------
.cseg
.org 0x0000
;---------------------------------------
; byte constants:
;
.equ k00 = 0x00 ;
.equ k01 = 0x01 ;
.equ k02 = 0x02 ;
.equ k03 = 0x03 ;
.equ k04 = 0x04 ;
.equ k06 = 0x06 ;
.equ k07 = 0x07 ;
.equ k08 = 0x08 ;
.equ k0B = 0x0B ;
.equ k18 = 0x18 ;
.equ k3A = 0x3A ; ‘:’
.equ k52 = 0x52 ; ‘R’
.equ k66 = 0x66 ; ‘f’
.equ k6E = 0x6E ; ‘n’
.equ k7A = 0x7A ; ‘z’
.equ k7D = 0x7D ; ‘}’
.equ k7F = 0x7F ; ‘’
.equ k80 = 0x80 ;
.equ k81 = 0x81 ;
.equ k8E = 0x8E ;
.equ k98 = 0x98 ;
.equ kB0 = 0xB0 ; ‘∞’
.equ kB1 = 0xB1 ; ‘±’
.equ kDF = 0xDF ; ‘fl’
.equ kE8 = 0xE8 ; ‘Ë’
.equ kFC = 0xFC ; ‘¸’
.equ kFD = 0xFD ; ‘˝’
.equ kFF = 0xFF ; ‘ˇ’
;
; io register addresses:
;
.equ p15 = 0x15
.equ p24 = 0x24
.equ p25 = 0x25
.equ p26 = 0x26
.equ p3D = 0x3D
.equ p3E = 0x3E
.equ p3F = 0x3F
;
; bit numbers:
;
.equ b0 = 0x00
.equ b1 = 0x01
.equ b2 = 0x02
.equ b3 = 0x03
.equ b4 = 0x04
.equ b5 = 0x05
.equ b6 = 0x06
.equ b7 = 0x07
;---------------------------------------
;
L0000:
jmp _reset ; L0061
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L009D
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
jmp L007E
; ----------- jump on last line
nop
nop
.dw 0x0024 ; pc=0x0036(0x006C)
.dw 0x0027 ; pc=0x0037(0x006E)
.dw 0x002A ; pc=0x0038(0x0070)
nop
nop
.dw 0x0025 ; pc=0x003B(0x0076)
.dw 0x0028 ; pc=0x003C(0x0078)
.dw 0x002B ; pc=0x003D(0x007A)
nop
nop
.dw 0x0023 ; pc=0x0040(0x0080)
.dw 0x0026 ; pc=0x0041(0x0082)
.dw 0x0029 ; pc=0x0042(0x0084)
cpc r0,r4
cpc r0,r4
cpc r0,r4
cpc r0,r4
muls r16,r18
muls r16,r18
muls r16,r18
mulsu r16,r19
mulsu r16,r19
mulsu r16,r19
muls r16,r17
sbc r0,r4
and r1,r0
ld r4,Z
muls r16,r17
sbc r0,r4
and r1,r0
muls r16,r17
sbc r0,r4
and r1,r0
nop
cpc r16,r16
muls r16,r16
.dw 0x0001 ; pc=0x005A(0x00B4)
mulsu r16,r16
cpc r0,r20
nop
nop
nop
nop
;
_reset:
; L0061:
clr r1
out p3F,r1
ldi r28,kFF
ldi r29,k08
out p3E,r29
out p3D,r28
ldi r17,k01
ldi r26,k00
ldi r27,k01
ldi r30,k3A
ldi r31,k04
rjmp L006F
; ----------- jump on last line
L006D:
lpm r0,Z+
st X+,r0
L006F:
cpi r26,k02
cpc r27,r17
brne L006D
; ----- branch on last line
ldi r17,k01
ldi r26,k02
ldi r27,k01
rjmp L0077
; ----------- jump on last line
L0076:
st X+,r1
L0077:
cpi r26,k0B
cpc r27,r17
brne L0076
; ----- branch on last line
call L020C
jmp L021B
; ----------- jump on last line
L007E:
jmp L0000
; ----------- jump on last line
L0080:
lds r24,D0100
ldi r22,k01
call L01B8
ldi r22,kE8
ldi r23,k03
ldi r24,k00
ldi r25,k00
call L00E5
lds r24,D0100
ldi r22,k00
call L01B8
ldi r22,kE8
ldi r23,k03
ldi r24,k00
ldi r25,k00
call L00E5
ret
;--------------------*
; pc=0x97(0x12E)
;
L0097:
lds r24,D0100
ldi r22,k01
call L0179
ret
;--------------------*
; pc=0x9D(0x13A)
;
L009D:
push r1
push r0
in r0,p3F
push r0
clr r1
push r18
push r19
push r24
push r25
push r26
push r27
lds r24,D0106
lds r25,D0107
lds r26,D0108
lds r27,D0109
lds r19,D010A
adiw r24,k01
adc r26,r1
adc r27,r1
mov r18,r19
subi r18,kFD
cpi r18,k7D
brcs L00BD
; — branch on last line
subi r18,k7D
adiw r24,k01
adc r26,r1
adc r27,r1
L00BD:
sts D010A,r18
sts D0106,r24
sts D0107,r25
sts D0108,r26
sts D0109,r27
lds r24,D0102
lds r25,D0103
lds r26,D0104
lds r27,D0105
adiw r24,k01
adc r26,r1
adc r27,r1
sts D0102,r24
sts D0103,r25
sts D0104,r26
sts D0105,r27
pop r27
pop r26
pop r25
pop r24
pop r19
pop r18
pop r0
out p3F,r0
pop r0
pop r1
reti
;----------------------*
; pc=0xE5(0x1CA)
;
L00E5:
movw r18,r22
movw r20,r24
in r23,p3F
cli
lds r24,D0102
lds r25,D0103
lds r26,D0104
lds r27,D0105
in r22,p26
; --------- this is skippy
sbis p15,b0
rjmp L00F9
; -----– last may be skipped
; pc=0xF4(0x1E8)
;
cpi r22,kFF
breq L00F9
; ----- branch on last line
adiw r24,k01
adc r26,r1
adc r27,r1
L00F9:
out p3F,r23
mov r27,r26
mov r26,r25
mov r25,r24
clr r24
add r24,r22
adc r25,r1
adc r26,r1
adc r27,r1
ldi r22,k02
L0103:
lsl r24
rol r25
rol r26
rol r27
dec r22
brne L0103
; ----- branch on last line
movw r22,r24
rjmp L0138
; ----------- jump on last line
L010B:
in r31,p3F
cli
lds r24,D0102
lds r25,D0103
lds r26,D0104
lds r27,D0105
in r30,p26
; -----– this is skippy
sbis p15,b0
rjmp L011D
; ------- last may be skipped
; pc=0x118(0x230)
;
cpi r30,kFF
breq L011D
; — branch on last line
adiw r24,k01
adc r26,r1
adc r27,r1
L011D:
out p3F,r31
mov r27,r26
mov r26,r25
mov r25,r24
clr r24
add r24,r30
adc r25,r1
adc r26,r1
adc r27,r1
ldi r30,k02
L0127:
lsl r24
rol r25
rol r26
rol r27
dec r30
brne L0127
; — branch on last line
sub r24,r22
sbc r25,r23
subi r24,kE8
sbci r25,k03
brcs L010B
; — branch on last line
subi r18,k01
sbci r19,k00
sbci r20,k00
sbci r21,k00
subi r22,k18
sbci r23,kFC
L0138:
cp r18,r1
cpc r19,r1
cpc r20,r1
cpc r21,r1
brne L010B
; — branch on last line
ret
;--------------------*
; pc=0x13E(0x27C)
;
L013E:
sei
in r24,p24
ori r24,k02
out p24,r24
in r24,p24
ori r24,k01
out p24,r24
in r24,p25
ori r24,k02
out p25,r24
in r24,p25
ori r24,k01
out p25,r24
ldi r30,k6E
ldi r31,k00
ld r24,Z
ori r24,k01
st Z,r24
ldi r30,k81
ldi r31,k00
st Z,r1
ld r24,Z
ori r24,k02
st Z,r24
ld r24,Z
ori r24,k01
st Z,r24
ldi r30,k80
ldi r31,k00
ld r24,Z
ori r24,k01
st Z,r24
ldi r30,kB1
ldi r31,k00
ld r24,Z
ori r24,k04
st Z,r24
ldi r30,kB0
ldi r31,k00
ld r24,Z
ori r24,k01
st Z,r24
ldi r30,k7A
ldi r31,k00
ld r24,Z
ori r24,k04
st Z,r24
ld r24,Z
ori r24,k02
st Z,r24
ld r24,Z
ori r24,k01
st Z,r24
ld r24,Z
ori r24,k80
st Z,r24
sts D00C1,r1
ret
;--------------------*
; pc=0x179(0x2F2)
;
L0179:
push r28
push r29
mov r20,r24
ldi r21,k00
movw r24,r20
subi r24,k66
sbci r25,kFF
movw r30,r24
lpm r19,Z
subi r20,k7A
sbci r21,kFF
movw r30,r20
lpm r24,Z
tst r24
breq L01B5
; — branch on last line
ldi r25,k00
lsl r24
rol r25
movw r30,r24
subi r30,k98
sbci r31,kFF
lpm r26,Z+
lpm r27,Z
movw r30,r24
subi r30,k8E
sbci r31,kFF
lpm r28,Z+
lpm r29,Z
tst r22
brne L01A1
; — branch on last line
in r18,p3F
cli
ld r24,X
mov r25,r19
com r25
and r24,r25
st X,r24
ldd r24,Y+o00
and r24,r25
rjmp L01AC
; ----------- jump on last line
L01A1:
cpi r22,k02
brne L01AF
; ----- branch on last line
in r18,p3F
cli
ld r24,X
mov r25,r19
com r25
and r24,r25
st X,r24
ldd r24,Y+o00
or r24,r19
L01AC:
std Y+o00,r24
out p3F,r18
rjmp L01B5
; ----------- jump on last line
L01AF:
in r25,p3F
cli
ld r24,X
or r24,r19
st X,r24
out p3F,r25
L01B5:
pop r29
pop r28
ret
;----------------------*
; pc=0x1B8(0x370)
;
L01B8:
mov r20,r24
ldi r21,k00
movw r24,r20
subi r24,k52
sbci r25,kFF
movw r30,r24
lpm r18,Z
movw r24,r20
subi r24,k66
sbci r25,kFF
movw r30,r24
lpm r25,Z
subi r20,k7A
sbci r21,kFF
movw r30,r20
lpm r19,Z
tst r19
brne L01CB
; ----- branch on last line
rjmp L020B
; ----------- jump on last line
L01CB:
tst r18
breq L01F7
; — branch on last line
cpi r18,k03
breq L01DD
; — branch on last line
cpi r18,k04
brcc L01D6
; — branch on last line
cpi r18,k01
breq L01E7
; — branch on last line
cpi r18,k02
brne L01F7
; — branch on last line
rjmp L01EA
; ----------- jump on last line
L01D6:
cpi r18,k06
breq L01EE
; — branch on last line
cpi r18,k07
breq L01F2
; — branch on last line
cpi r18,k04
brne L01F7
; — branch on last line
rjmp L01E1
; ----------- jump on last line
L01DD:
lds r24,D0080
andi r24,k7F
rjmp L01E4
; ----------- jump on last line
L01E1:
lds r24,D0080
andi r24,kDF
L01E4:
sts D0080,r24
rjmp L01F7
; ----------- jump on last line
L01E7:
in r24,p24
andi r24,k7F
rjmp L01EC
; ----------- jump on last line
L01EA:
in r24,p24
andi r24,kDF
L01EC:
out p24,r24
rjmp L01F7
; ----------- jump on last line
L01EE:
lds r24,D00B0
andi r24,k7F
rjmp L01F5
; --------- jump on last line
L01F2:
lds r24,D00B0
andi r24,kDF
L01F5:
sts D00B0,r24
L01F7:
mov r30,r19
ldi r31,k00
lsl r30
rol r31
subi r30,k8E
sbci r31,kFF
lpm r26,Z+
lpm r27,Z
in r18,p3F
cli
tst r22
brne L0207
; — branch on last line
ld r24,X
com r25
and r24,r25
rjmp L0209
; ----------- jump on last line
L0207:
ld r24,X
or r24,r25
L0209:
st X,r24
out p3F,r18
L020B:
ret
;--------------------*
; pc=0x20C(0x418)
;
L020C:
push r28
push r29
call L013E
call L0097
ldi r28,k00
ldi r29,k00
L0214:
call L0080
sbiw r28,k00
breq L0214
; — branch on last line
call L0000
rjmp L0214
; ----------- jump on last line
L021B:
cli
L021C:
rjmp L021C
; --------- jump on last line
; pc=0x21D(0x43A)
;
.dw 0x000D ; pc=0x021D(0x043A)
;
; last flash byte address = 0x043B
; last flash word address = 0x021D
;---------------------------------------
.dseg
.org 0x0080
;
D0080:
.byte 48
D00B0:
.byte 17
D00C1:
.byte 63
D0100:
.byte 2
D0102:
.byte 1
D0103:
.byte 1
D0104:
.byte 1
D0105:
.byte 1
D0106:
.byte 1
D0107:
.byte 1
D0108:
.byte 1
D0109:
.byte 1
D010A:
;
; last lds/sts data byte at 0x010A
;---------------------------------------
;
You can then use Boomerang to recreate C from ASM.
Extremely amusing (possibly just to me) side note:
You may know that @Daniel_Garcia and I work at Veracode, where for over a decade we’ve built what is probably world’s most advanced fully automated decompiler (and enterprise application security scanner, but that’s not the point here). But what you may not know, is that in 2006 we also hired the original Boomerang guys to join us!
Anyway, it was an amusing crossing-the-streams moment to see discussion of Boomerang here.
Sadly, Veracode’s system doesn’t support decompiling AVR binaries. Yet.
Not sure what vulnerabilities we’d scan for; there’s not a lot of room for SQL Injection in a device with 2K of RAM. Maybe new classes of vulnerabilities, like “Battery Burndown” or “Pixel Overflow”…
Well that does explain alot @Mark_Kriegsman . I actually used veracode for some code scanning a few years ago with my previous employer. neat.
For this issue, I actually dont need to know the code itself at all. But it seems that to get the sketch (hex) off the device, it pulls the devices bootloader, so I can switch it to a different type of arduino. ah well.
Re-burn the correct bootloader after loading?
sadly i dont have time to dig into how before i head out for the mini vacation/festival
something i’ll look into afterwards
Tools > burn bootloader