Hacking Hardware Picofly - a HWFLY switch modchip

KAAAsS

Member
Newcomer
Joined
Feb 17, 2023
Messages
7
Trophies
0
XP
37
Country
China
@renoob Good news! It means the firmware had started the decryption. What about the register value? Could you print the value of R3 and R6?

My fault, misreading that
 
Last edited by KAAAsS,

KAAAsS

Member
Newcomer
Joined
Feb 17, 2023
Messages
7
Trophies
0
XP
37
Country
China
Just notice that in emulation, the program frequently does R/W to SYSCFG before the decryption, and 0x40004014 is SYSCFG_DBGFORCE. I'm not familiar with RP2040, could anyone tell me if is this an anti-debugger or sort of thing? just a guess

Code:
IO_MEM[SYSCFG] write:pc:200200CA addr:40006014 size:4 value:4
IO_MEM[SYSCFG] write:pc:20020132 addr:40006014 size:4 value:2
IO_MEM[SYSCFG] write:pc:200200DE addr:40007014 size:4 value:4
IO_MEM[SYSCFG] read:pc:20020148 addr:40004014 size:4
....
IO_MEM[SYSCFG] write:pc:200200CA addr:40006014 size:4 value:40
IO_MEM[SYSCFG] write:pc:20020138 addr:40007014 size:4 value:20
IO_MEM[SYSCFG] write:pc:200200DE addr:40007014 size:4 value:40
IO_MEM[SYSCFG] read:pc:20020148 addr:40004014 size:4
 

thesjaakspoiler

Well-Known Member
Member
Joined
Nov 20, 2018
Messages
993
Trophies
0
Age
124
XP
1,521
Country
Afghanistan
Just notice that in emulation, the program frequently does R/W to SYSCFG before the decryption, and 0x40004014 is SYSCFG_DBGFORCE. I'm not familiar with RP2040, could anyone tell me if is this an anti-debugger or sort of thing? just a guess

Code:
IO_MEM[SYSCFG] write:pc:200200CA addr:40006014 size:4 value:4
IO_MEM[SYSCFG] write:pc:20020132 addr:40006014 size:4 value:2
IO_MEM[SYSCFG] write:pc:200200DE addr:40007014 size:4 value:4
IO_MEM[SYSCFG] read:pc:20020148 addr:40004014 size:4
....
IO_MEM[SYSCFG] write:pc:200200CA addr:40006014 size:4 value:40
IO_MEM[SYSCFG] write:pc:20020138 addr:40007014 size:4 value:20
IO_MEM[SYSCFG] write:pc:200200DE addr:40007014 size:4 value:40
IO_MEM[SYSCFG] read:pc:20020148 addr:40004014 size:4
It looks to be the opposite, some sort of software debug port for the processor :
https://raspberrypi.github.io/pico-sdk-doxygen/syscfg_8h_source.html
_REG_(SYSCFG_DBGFORCE_OFFSET) // SYSCFG_DBGFORCE
// Directly control the SWD debug port of either processor
// 0x00000080 [7] : PROC1_ATTACH (0): Attach processor 1 debug port to syscfg controls, and disconnect it from...
// 0x00000040 [6] : PROC1_SWCLK (1): Directly drive processor 1 SWCLK, if PROC1_ATTACH is set
// 0x00000020 [5] : PROC1_SWDI (1): Directly drive processor 1 SWDIO input, if PROC1_ATTACH is set
// 0x00000010 [4] : PROC1_SWDO (0): Observe the value of processor 1 SWDIO output
// 0x00000008 [3] : PROC0_ATTACH (0): Attach processor 0 debug port to syscfg controls, and disconnect it from...
// 0x00000004 [2] : PROC0_SWCLK (1): Directly drive processor 0 SWCLK, if PROC0_ATTACH is set
// 0x00000002 [1] : PROC0_SWDI (1): Directly drive processor 0 SWDIO input, if PROC0_ATTACH is set
// 0x00000001 [0] : PROC0_SWDO (0): Observe the value of processor 0 SWDIO output
io_rw_32 dbgforce;
Since the pico has 2 cores, maybe the debug/watchdog monitor is running on the other core?
 
  • Wow
Reactions: impeeza

KAAAsS

Member
Newcomer
Joined
Feb 17, 2023
Messages
7
Trophies
0
XP
37
Country
China
@thesjaakspoiler Thx for the info! But I still suspect it's an anti-debugger because the program only read the value of SYSCFG_DBGFORCE. So I guess it is detection or something? Besides, it is weird that the address 0x40006014 and 0x40007014 are not documented in RP2040 datasheet (maybe i miss sth?).
 
  • Like
Reactions: FruithatMods

thesjaakspoiler

Well-Known Member
Member
Joined
Nov 20, 2018
Messages
993
Trophies
0
Age
124
XP
1,521
Country
Afghanistan
SYSCFG_DBGFORCE_OFFSET is an offset so I think you can set it to whatever you want it to.
I also don't know the details but the following forum post talks about running a debugger over USB on 1 core that debugs another core. If you use an external debugger (like another pi) then you physically connect the 2 boards but with the pico you can also 'wire' 1 core to the other and have the processor deal with it like an external debugger is used.
Here they set it to 0x40004014 :
https://forums.raspberrypi.com/viewtopic.php?t=313226
My guess is that the author of the original used this method to debug the pico without the need for any additional hardware Why use an external debugger if you have 1 core to spare and the USB connection available?
That you see code for core 0 and 1 might be because the core might be something generic that can run on both cores.
 

renoob

Active Member
Newcomer
Joined
Feb 6, 2023
Messages
42
Trophies
0
XP
157
Country
France
SYSCFG_DBGFORCE_OFFSET is an offset so I think you can set it to whatever you want it to.
I also don't know the details but the following forum post talks about running a debugger over USB on 1 core that debugs another core. If you use an external debugger (like another pi) then you physically connect the 2 boards but with the pico you can also 'wire' 1 core to the other and have the processor deal with it like an external debugger is used.
Here they set it to 0x40004014 :
https://forums.raspberrypi.com/viewtopic.php?t=313226
My guess is that the author of the original used this method to debug the pico without the need for any additional hardware Why use an external debugger if you have 1 core to spare and the USB connection available?
That you see code for core 0 and 1 might be because the core might be something generic that can run on both cores.
Yeah I've used that to debug zero

https://github.com/majbthrd/pico-debug

But you need to build official OpenOCD to make it work or you will have an error
 

flynnsmt4

Member
Newcomer
Joined
Feb 20, 2023
Messages
11
Trophies
0
XP
155
Country
United States
@thesjaakspoiler Thx for the info! But I still suspect it's an anti-debugger because the program only read the value of SYSCFG_DBGFORCE. So I guess it is detection or something? Besides, it is weird that the address 0x40006014 and 0x40007014 are not documented in RP2040 datasheet (maybe i miss sth?).
Those addresses are documented, every peripheral MMIO page gets three extra pages from the base address for atomic IO; they're all writes to the DBGFORCE register. Specifically, on each core, it writes a data bit in SWDI by triggering a falling edge on SWCLK. The sequence is something like

(atomic) OR swclk
(atomic) OR swdi
(atomic) AND ~swclk i.e. set swclk to 0

<and then it reads the entire register, presumably masking all bits except swdo. maybe they check that swdo = swdi?>

Assuming they're attached to the core (otherwise it doesn't do anything(?)) it's probably just trying to interfere with someone attaching something to the SWD pins on the RP2040.

edit, you can read section 2.1 of the rp2040 datasheet if you need to know atomic write mappings
 

renoob

Active Member
Newcomer
Joined
Feb 6, 2023
Messages
42
Trophies
0
XP
157
Country
France
Still pursuing unique id. Managed to debug the actual get_unique_id call in the main function and it seems if ID is altered (at least the way I did it) it adds additional data to it:

Code:
INJECTED ID
0x10000718 in ?? ()
(gdb) x/s $r0
0x20041fa0:     "\346a\034\267\037\062h)\bG\003\265P\002"
vs unaltered

Code:
ORIGINAL ID
0x10000718 in ?? ()
(gdb) x/s $r0
0x20041fa0:     "\346aA\004\003y\247\071"
So it adds additional:
Code:
\bG\003\265P\002
Tried with different picos to confirm and different injected IDs its always the same.

Will test with pico example and that other program that which accepted injected id to see are there the same results

Edit: Tested and nop there are no anomalies like this in pico-example or that other program. Everything fine. Also double check that program with the injection and it works.
The only thing is that program if ID is not correct then it adds some data to it, but if its correct (injection) then it shows normal ID string without any additional data (so its reversed than this above)
Pico example shows normal ID strings no matter is it injected or not
(that other program I'm referring is this https://forums.raspberrypi.com/viewtopic.php?t=336409 and it accepts injected ID)
 
Last edited by renoob,

Mansi

Well-Known Member
Newcomer
Joined
Jan 14, 2023
Messages
70
Trophies
0
Age
30
XP
331
Country
Belarus
Official firmware updated to FW 16.0.0!

Code:
System Titles
New sysmodule ngc was added (0100000000000050).
All sysmodules were updated (excluding stubbed-lbl).
Most SystemData were updated, except for: Chinese and Korean dictionaries, Dictionary, AvatarImage, UrlBlackList, ControllerIcon, ApplicationBlackList, FunctionBlackList.
Most applets were updated, except for: cabinet, controller, netConnect, swkbd, miiEdit, starter, maintenance.
NPDM changes (besides usual version-bump):

boot2.ProdBoot now has access to ncm.
friends no longer has access to csrng.
nifm now has htc:nd access.
nifm, ldn, ns: pl:u access was replaced with pl:s.
ns now has access to ns:am2 and ns:su (for GetService).
nim no longer has access to spl:.
vi now has pl:u access.
glue now has hosted-service pl:u access (moved from sdb) and access to svcCreateSharedMemory.
fatal had access for the following removed: nvdrv:s, pl:u, vi:s.
sdb had access for pl:u (hosted-service) and svcCreateSharedMemory removed.
qlaunch, playerSelect, photoViewer, myPage: access to ngc:u was added.
The SafeMode bootpkgs KIP for PCV had "Default CPU Core" changed from 3 to 63.

RomFs changes:

CertStore: "/ssl_TrustedCerts.bdf" updated and "/ssl_TrustedCerts.Ounce.bdf" added.
ErrorMessage: updated
BrowserDll:
"/browser/MediaControlsInline.css" updated
"/browser/MediaControlsInline.js" updated
"/browser/UserCssCore0.dat" added
"/browser/UserCss.dat" updated
"/buildinfo/buildinfo.dat" updated
"/gfxShader/" added, which contains "BrowserOffscreenDrawer.bnsh".
"/lyt/Browse/Page.arc" updated
"/nro/" The various NROs located under here were updated.
Help: "/legallines.htdocs/img/HDMI.png" and "/legallines.htdocs/index.html" were updated.
NgWord: updated.
LocalNews: "/image/LnSupIntro/main_Other.jpg", "/message/EUnl/localNews.msbt.szs", "/message/revision.txt" updated.
Eula: "/KRko/Eula.msbt.szs" and "/revision.txt" updated.
FirmwareDebugSettings: updated
NgWord2: updated. Added "/ac_similar_form_nx" and "/table_similar_form_nx".
NgWordT: "/mars_dirty_words_db" updated
applets: various UI/message/gfx data updated.
web-applets: "/buildinfo/buildinfo.dat" and "/.nrr/modules.nrr" updated.

Source: https://switchbrew.org/wiki/16.0.0
 

KAAAsS

Member
Newcomer
Joined
Feb 17, 2023
Messages
7
Trophies
0
XP
37
Country
China
Those addresses are documented, every peripheral MMIO page gets three extra pages from the base address for atomic IO; they're all writes to the DBGFORCE register. Specifically, on each core, it writes a data bit in SWDI by triggering a falling edge on SWCLK. The sequence is something like

(atomic) OR swclk
(atomic) OR swdi
(atomic) AND ~swclk i.e. set swclk to 0

<and then it reads the entire register, presumably masking all bits except swdo. maybe they check that swdo = swdi?>

Assuming they're attached to the core (otherwise it doesn't do anything(?)) it's probably just trying to interfere with someone attaching something to the SWD pins on the RP2040.

edit, you can read section 2.1 of the rp2040 datasheet if you need to know atomic write mappings
Thx for the info! that really helps me to understand the program since it uses the atomic IO a lot. Since the program looks like uses several MMIO addresses to pass data in the decryption, I guess this is the reason that my emulation got wrong. Will try to implement this later.

EDIT: sadly the decrypted value has not changed :(

Post automatically merged:

Still pursuing unique id. Managed to debug the actual get_unique_id call in the main function and it seems if ID is altered (at least the way I did it) it adds additional data to it:

Code:
INJECTED ID
0x10000718 in ?? ()
(gdb) x/s $r0
0x20041fa0:     "\346a\034\267\037\062h)\bG\003\265P\002"
vs unaltered

Code:
ORIGINAL ID
0x10000718 in ?? ()
(gdb) x/s $r0
0x20041fa0:     "\346aA\004\003y\247\071"
So it adds additional:
Code:
\bG\003\265P\002
Tried with different picos to confirm and different injected IDs its always the same.

Will test with pico example and that other program that which accepted injected id to see are there the same results

Edit: Tested and nop there are no anomalies like this in pico-example or that other program. Everything fine. Also double check that program with the injection and it works.
The only thing is that program if ID is not correct then it adds some data to it, but if its correct (injection) then it shows normal ID string without any additional data (so its reversed than this above)
Pico example shows normal ID strings no matter is it injected or not
(that other program I'm referring is this https://forums.raspberrypi.com/viewtopic.php?t=336409 and it accepts injected ID)
Just rechecked this part code, if I'm not wrong, it doesn't matter whether there is extra data following the ID, the rest part of the function 0x1000070C just reads the first 8 bytes from the ID stored in stack and expands it to 265 bytes. The extra data shown in the gdb might be because you use "/s" mode, and gdb tries to read until a terminating zero.
 
Last edited by KAAAsS,

renoob

Active Member
Newcomer
Joined
Feb 6, 2023
Messages
42
Trophies
0
XP
157
Country
France
Yeah first 8 bytes are correct (the ID), but its kinda odd that the additional data appears only when id is injected. Reading full 16 bytes as hex gives first 8 as ID and next 8 as 00 when there is no injection, but after injection last 8 are not 00 anymore
 

KAAAsS

Member
Newcomer
Joined
Feb 17, 2023
Messages
7
Trophies
0
XP
37
Country
China
Yeah first 8 bytes are correct (the ID), but its kinda odd that the additional data appears only when id is injected. Reading full 16 bytes as hex gives first 8 as ID and next 8 as 00 when there is no injection, but after injection last 8 are not 00 anymore
Since 0x20041fa0 is located in stack and didn't get cleared before get_unique_id, I guess those data were written by other functions. The difference between injected and original firmware might be because the injected firmware didn't run the flash_get_unique_id function, so the stack contents become different.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    SylverReZ @ SylverReZ: @Psionic Roshambo, Soi soi soi rofl rofl rofl