View Single Post
Old 02-19-2016, 07:24 PM   #13
ero-sennin
Junior Member
ero-sennin began at the beginning.
 
Posts: 3
Karma: 10
Join Date: Feb 2016
Device: Kobo Aura
OK, figured out how to patch libnickel.so.1.0.0 to disable the Critical Error popup. This way it would accept any non-empty registration data, like in older firmwares.

Spoiler:

The string "Critical Error" is referenced from these two functions:

Code:
008A85D0: _ZN18Nickel3Application20finishInitializationEv ; Nickel3Application::finishInitialization()

008FC95C: _ZN19PlugWorkflowManager16onDoneProcessingEv    ; PlugWorkflowManager::onDoneProcessing()
Both functions contain a similar piece of code:

Code:
<...>
008FCA3E                 BL              sub_643568 ; load and validate user data
008FCA42                 CBNZ            R0, no_error
008FCA44                 LDR             R1, =(_ZN19PlugWorkflowManager16staticMetaObjectE_ptr - 0xE29760)
008FCA46                 ADDS            R6, R7, #4
008FCA48                 LDR             R2, =(aCriticalError - 0x8FCA58)
008FCA4A                 MOV.W           LR, #0xFFFFFFFF
008FCA4E                 MOV             R3, R0  ; int
008FCA50                 MOV             R0, R6  ; this
008FCA52                 LDR             R1, [R5,R1] ; _ZN19PlugWorkflowManager16staticMetaObjectE_ptr ; char *
008FCA54                 ADD             R2, PC  ; "Critical Error"
008FCA56                 STR.W           LR, [SP,#0x14+var_14]
008FCA5A                 BLX.W           _ZNK11QMetaObject2trEPKcS1_i ; QMetaObject::tr(char const*,char const*,int)
008FCA5E                 MOV             R0, R6
008FCA60                 MOVS            R1, #1
008FCA62                 BLX.W           j__ZN19AccountSignOutMixin17showSignOutDialogE7QStringb ; AccountSignOutMixin::showSignOutDialog(QString,bool)
008FCA66                 LDR             R0, [R7,#0xC+var_8]
008FCA68                 LDR             R3, [R0]
008FCA6A                 CBNZ            R3, loc_8FCA80
008FCA6C                 MOVS            R1, #2
008FCA6E                 MOVS            R2, #4
008FCA70                 BLX.W           _ZN10QArrayData10deallocateEPS_jj ; QArrayData::deallocate(QArrayData*,uint,uint)
008FCA74
008FCA74 no_error        ; continue normally
<...>
This code calls a function at 0x643568 that loads and validates the user data. If that function returns 0, the Critical Error dialog is shown. Otherwise, no dialog appears and everything is fine. So we can just modify that function to always return a non-zero value.

The end part of the load-and-validate-user-data function at 0x643568, where the result is returned, looks like this:

Code:
006435A6                 ADDS            R0, R5, #1  ; return 0 if R5 == -1
006435A8                 ADD.W           R7, R7, #0x3C
006435AC                 IT NE
006435AE                 MOVNE           R0, #1      ; otherwize return 1
006435B0                 MOV             SP, R7
006435B2                 POP             {R4-R7,PC}  ; return from function
Changing the first line to

Code:
006435A6                 ADDS            R0, R5, #2  ; return 1 if R5 == -1
will make the function always return 1. Done!


Here is the patch for libnickel.so.1.0.0 from the 3.19.5761 firmware:

Code:
<Patch>
patch_name = `Accept any registration data, disable the Critical Error dialog`
patch_enable = `yes`
replace_bytes = 6435A6, 68, A8
</Patch>
The only problem is that the patch would have to be manually updated for future firmwares. Perhaps we could find out how to generate valid registration data that would work with unpatched firmwares?
ero-sennin is offline   Reply With Quote