Hi all,
I am new to this forum and happy to be part of it. I am facing one problem. Hope you all can take a look at this.
I have an EAP-SIM application which needs to be ported to Windows CE Pocket PC 2003. It will probably run on HP iPAQ. I need to get the IMSI of the SIM card and run the GSM (A3/A5/A8) algorithms through my application.
After a lot of research, i found it might be possible through AT commands and with the help of RIL(Radio Interface Layer). I tried some samples, but is not working properly. I saw some AT commands in this link
http://ftp.rz.tu-bs.de/pub/mirror/cc..._log_commented
Next I tried this with RIL.
I need to know how i can get IMSI and send some PDU to the SIM card to run the algorithm. Is it possible ? through RIL ? AT command ? . Your valuable help or suggestion is expected.
-------------------------------------------------------------------
const BYTE SELECT_FILE_CMD[] = {(BYTE)0xA0, (BYTE)0xA4, (BYTE)0x00, (BYTE)0x00, (BYTE)0x02,(BYTE)0x3F,(BYTE)0x00};
const BYTE GSM_DIR_CMD[] = {(BYTE)0xA0, (BYTE)0xA4, (BYTE)0x00, (BYTE)0x00, (BYTE)0x02,(BYTE)0x7F,(BYTE)0x20};
const BYTE SELECT_EF_IMSI_CMD[] = {(BYTE)0xA0, (BYTE)0xA4, (BYTE)0x00, (BYTE)0x00, (BYTE)0x02,(BYTE)0x6F,(BYTE)0x07};
const BYTE GET_IMSI_CMD[] = {(BYTE)0xA0,(BYTE)0xB0,(BYTE)0x00,(BYTE)0x00, (BYTE)0x09 };
const BYTE READ_IMSI_CMD[] = {(BYTE)0xA0,(BYTE)0xC0,(BYTE)0x00,(BYTE)0x00, (BYTE)0x09 };
result = RIL_Initialize(1, ResultCallback, NotifyCallback, dwNotificationClasses, g_dwParam, &g_hRil);
res_UserIdentity = RIL_GetUserIdentity(g_hRil);
//res_SelectFile = RIL_SendSimCmd(g_hRil, SELECT_FILE_CMD,sizeof(SELECT_FILE_CMD));
//res_Select_IMSI = RIL_SendSimCmd(g_hRil, SELECT_EF_IMSI_CMD,sizeof(SELECT_EF_IMSI_CMD));
//res_Get_IMSI = RIL_SendSimCmd(g_hRil, GET_IMSI_CMD,sizeof(GET_IMSI_CMD));
//res_Read_IMSI = RIL_SendSimCmd(g_hRil, READ_IMSI_CMD,sizeof(READ_IMSI_CMD));
-------------------------------------------------------
Thanks,
Hi, could you repost the link you added, its not working when I click on it.
The commands to select the IMSI seem correct, you have the address right, although I think you might have the last 2 in the wrong order. The 0xb0 command is read binary, and 0xc0 is get response. Typically you would select 3f00, 7f20, 6f07, then send the response command with the length as the final byte (given as the second returned byte from the previous command). You then use the read binary command with the length as the final byte.
Having said that, as you already know the length, you could skip the response command altogether.
here is the trace from my PC based program im developing when selecting the IMSI:
A0 A4 00 00 02 3F 00
A0 A4 00 00 02 7F 20
A0 A4 00 00 02 6F 07
9F 0F
A0 C0 00 00 0F
90 00 00 00 00 09 6F 07 04 00 1D 00 1D 01 02 00 00
A0 B0 00 00 09
IMSI: 90 00 ......
Hi,
Thanks for your reply. Please find the link below
http://ftp.rz.tu-bs.de/pub/mirror/ccc_Chaos_Computer_Club/ftp.ccc.de/gsm/gsm_log_commented
The real problem is am using RIL. In RIL_SenSimCmd ( ), the error code i got is
80004001 which means its not implemented. I am using HP iPAQ. Does this execution of AT commands depends upon the mobile phone ? As you mentioned about your PC program,Are you using smart card reader or something else ? Can you please tell me how you did it ?
Right now am just trying to send a single AT command to select the GSM file after RIL initialization. That itself is failing.
const BYTE GSM_DIR_CMD[] = {(BYTE)0xA0, (BYTE)0xA4, (BYTE)0x00, (BYTE)0x00, (BYTE)0x02 ,(BYTE)0x7F,(BYTE)0x20};
result = RIL_Initialize(1, ResultCallback, NotifyCallback, dwNotificationClasses, g_dwParam, &g_hRil);
if (result < 0)
{
wsprintf(szString,L"RIL_Init-%d",result);
ShowMessage(szString);
}
res_GSMDir = RIL_SendSimCmd(g_hRil, GSM_DIR_CMD,sizeof(GSM_DIR_CMD));
if (res_GSMDir < 0)
{
wsprintf(szString,L"res_GSMDir %x",res_GSMDir);
ShowMessage(szString);
print_error(-1 * res_GSMDir);
}
So I assume my iPAQ is not allowing me to execute commands ?. Please give a brief about this. Please let me know if you didnt get the link. I wil send it to your mail id..
Thanks,
My knowledge with AT commands and RIL is limited im afraid, but I'd guess ipaq's dont use the standard AT commands. The error being returned would suggest to me that the command is incorrect and not recognised, so you're probably sending it in the wrong format.
All I can do is point you to a few links you probably have already looked at, namely microsofts msdn article on RIL application
http://msdn2.microsoft.com/en-us/library/ms894929.aspx
and handhelds site, which may contain useful info on your device that could help in development.
http://handhelds.org/
As for my program, im writting it in VC++ using the scard platform. And yes, im using a card reader.
The command structure is:
CCardServer::SCardCommand(LPCSTR Cmd, LPSTR DataIn, INT DataInLen, LPSTR DataOut, INT DataOutLen)
Hi sanal,
sanal said:
... I have an EAP-SIM application which needs to be ported to Windows CE Pocket PC 2003.
Click to expand...
Click to collapse
EAP-SIM --> i wish you good luck
sanal said:
... I need to get the IMSI of the SIM card and run the GSM (A3/A5/A8) algorithms through my application.
After a lot of research, i found it might be possible through AT commands and with the help of RIL(Radio Interface Layer). I tried some samples, but is not working properly. I saw some AT commands in this link
Click to expand...
Click to collapse
why not using SIM Manager? see SIM Manager Reference at MSDN.
This API is available for PocketPC 2002 and later..
Here a codesnippet out of SIMSpider, which i've written some time ago..
(if SIM Manager fails, then it's probably not implemented by hp for your device..)
Code:
// dwAddress:
// 0x6F07: IMSI
// 0x6F20: KC Ciphering Key
void ReadSIM ( DWORD dwAddress )
{
HSIM hSim;
HRESULT hr = SimInitialize ( 0, NULL, NULL, &hSim );
if ( hr == S_OK )
{
SIMRECORDINFO sri;
memset ( &sri, 0, sizeof(sri) );
sri.cbSize = sizeof(sri);
hr = SimGetRecordInfo ( hSim, dwAddress, &sri );
if ( hr == S_OK )
{
DWORD dwBytesRead;
BYTE pBuf [ 4096 ];
hr = SimReadRecord ( hSim, dwAddress, sri.dwRecordType, NULL, (LPBYTE)pBuf, sizeof(pBuf), &dwBytesRead );
if ( hr == S_OK )
{
// here you can decode the data according to gsm-spec
// e.g. http://www.ttfn.net/techno/smartcards/gsm11-11.pdf
}
else
wprintf ( L"Failed to read Record!" );
}
hr = SimDeinitialize ( hSim );
}
else
wprintf ( L"SimInitialize failed with %08X", hr );
}
for EAP-SIM you may need the ciphering key too.. don't know for sure..
for decoding the sim-files you can find any needed info e.g. in http://www.ttfn.net/techno/smartcards/gsm11-11.pdf
and so on...
hope it helps
Cheers,
ikarus
Hi ikarus,
Thanks a lot for your reply. I am reached half way. Got IMSI and Kc with SIM Manager. What to do with the Run GSM Algorithms. I think for that we need to send some commands to SIM. I have no hope of doing algorithms execution through SIM manager. Any idea ?
Hello sanal,
you're right. With SIM Manager there seems to be no way for running gsm algorithms.
Furthermore i'm not sure if you really need the imsi and kc.
As far as i know for eap-sim you send the algorithm (sim) a random, which the nas (respectively the authentication-entity behind) sends to you.
I'm not very well experienced with this, so you're on your own.
hm.. you could have a look at RIL_SendRestrictedSimCmd, but there is no constant for "Run GSM Algorithm".
You could also try RIL_SendSimCmd and format the command according to gsm-specs. In the mentioned document there is a chapter 9 - Description of the commands ..
(but i guess an official gsm-spec would be more helpful)
Maybe another user can help more?
good luck !
ikarus
yes I think needs to do more research. Particularly whether iPAQ supports this AT commands. Bcoz as of i know phones restrict this command AT+CSIM. As you mentioned i have already checked the specs ,
as limbmaster said i need to check whether am sending the commands correct or wrong. But my doubt is when i try AT+CSIM through serial com, it says error. then This is bcoz phone is not allowing you. Then how RIL will work.. Anyway need to look how GSM algorithm can be done.
Related
OK, I know that global subclassing of windows is formally not supported. However, I have a few ideas of how to do it. First, I was wondering if anyone knows whether or not the internal window structure is similar to the internal structure used on Windows NT.
Also, I was wondering if anyone knows how to locate the internal window table. I figure that it's contained somewhere in GWES as it contains the USER functions. I've been researching CreateWindowEx, but I haven't been able to land on anything specific.
Thanks!
Here is info that I've digged in last 10 minutes. It can be incorrect.
chmckay said:
First, I was wondering if anyone knows whether or not the internal window structure is similar to the internal structure used on Windows NT.
Click to expand...
Click to collapse
It is completely different.
As far as I've seen from coredll decompilation the HWND is internally translated to internal CWindow class by an internal "static CWindow* CWindow::coredllPwndFromHwnd(HWND__*)" function defined in twinuser.obj file in thunks.lib in PlatformBuilder. I've dumped it from a COREDLL.PDB file from old PlatformBuilder 4.0beta. Here is it, cleaned from unnecessary function prototypes:
Code:
struct CWindow
{
struct CWindow* m_pcwndNext;
struct CWindow* m_pcwndParent;
struct CWindow* m_pcwndChild;
unsigned m_sig;
struct CWindow* m_pcwndOwner;
struct CWindow* m_pcwndOwned;
struct CWindow* m_pcwndNextOwned;
struct CWindow* m_pcwndRestore;
struct tagRECT m_rc;
struct tagRECT m_rcClient;
void* m_pgdiwnd;
void* m_pgdiwndClient;
void* m_pgdiwndClientUpdate;
struct tagRECT m_rcRestore;
struct _GENTBL* m_ptblProperties;
unsigned m_dwState;
struct ScrollBarInfoInternal* m_psbii;
DWORD* m_pszName;
struct MsgQueue* m_pmsgq;
DWORD m_himc;
unsigned m_grfStyle;
unsigned m_grfExStyle;
struct CWindowClass* m_pwc;
long m_lID;
long m_lUserData;
void* m_hprcCreator;
void* m_hthdCreator;
void* m_hprcWndProc;
int (*m_pfnWndProc)(HWND__*, DWORD, DWORD, int);
struct HRGN__* m_hrgnWindowRgn;
struct HRGN__* m_hrgnVisible;
struct HRGN__* m_hrgnUpdate;
struct HRGN__* m_hrgnClientVisible;
struct HRGN__* m_hrgnClientUpdate;
struct HMENU__* m_hmenu;
void* m_hprcDestroyer;
struct CWindow::__unnamed::__unnamed m;
unsigned m_grfBitFields;
DWORD m_rgdwExtraBytes[0];
};
The structure may have been changed in the current version of OS.
The code of coredllPwndFromHwnd() function taken from iMate 1.72 ROM:
Code:
.text:01F6E65C sub_1F6E65C ; COD
.text:01F6E65C ; sub
.text:01F6E65C 10 40 2D E9 STMFD SP!, {R4,LR}
.text:01F6E660 FE 24 C0 E3 BIC R2, R0, #0xFE000000
.text:01F6E664 2C 00 9F E5 LDR R0, =unk_1FC65AC ; this is a "g_dwGwesBase" variable
.text:01F6E668 00 10 90 E5 LDR R1, [R0]
.text:01F6E66C 01 40 82 E0 ADD R4, R2, R1
.text:01F6E670 1C 10 9F E5 LDR R1, =0x574E4457 ; Magic value? It is in m_sig member.
.text:01F6E674 0C 00 94 E5 LDR R0, [R4,#0xC]
.text:01F6E678 01 00 50 E1 CMP R0, R1
.text:01F6E67C 57 0E A0 13 MOVNE R0, #0x570
.text:01F6E680 08 00 80 13 ORRNE R0, R0, #8
.text:01F6E684 00 40 A0 13 MOVNE R4, #0
.text:01F6E688 72 0C 00 1B BLNE SetLastError
.text:01F6E68C 04 00 A0 E1 MOV R0, R4
.text:01F6E690 10 80 BD E8 LDMFD SP!, {R4,PC}
I can upload somewhere the complete dump of all structures from coredll, gwes, nk. But they are taken form old PlatformBuilder, because latest version has this data removed from PDB files.
I don't know the address that containf the head of this linked list, but probably it starts from the desktop window. So you can get CWindow of desktop and enumerate windows with m_pcwndNext/m_pcwndChild members.
The other problem is that we cannot determine the g_dwGwesBase value that is added to HWND to determine CWindow pointer.
One idea. You can try "GetWindowLong" to get data from CWindow structure. But its predefined offsets look very strange.
Mamaich,
Thank you VERY much. That was just the information I needed! I've managed to locate the class information and successfully subclass a window globally on the emulator (my cradle is at home, so I can't test this on my device).
Here's what I've learned that you might be interested in:
the g_dwGwesBase variable is actually a pointer to the virtual memory location of gwes.exe. Also, the 0xfe000000 value is specific to the processor. In this case, the value is (hwnd & ~0xfe000000), while on the x86/emulator platform, it is (hwnd & 0x1fffffff). I don't have access to the MIPS or SH3 libraries (as I don't have a full copy of Platform Builder).
Anyway, this is what the coredllPwndFromHwnd() function amounts to:
DWORD *wnd = (hwnd & ~0xfe000000) + g_dwGwesBase;
if( wnd[3] == 0x574e4457 )
return wnd;
else {
SetLastError(0x578);
return NULL;
}
The 0x574e4457 is not processor specific (as it appears in the x86 libs). Also, you easily replace the "+ g_dwGwesBase" with this:
DWORD *wnd = (DWORD*)MapPtrToProcess((LPVOID)(hwnd & ~0xfe000000), hHandleToGWES);
Thank you again for your help. Now, the only thing I have left to do is get the magic numbers for MIPS and SH3 and I'll be all set.
chmckay said:
The 0x574e4457 is not processor specific (as it appears in the x86 libs).
Click to expand...
Click to collapse
0x574e4457 == 'WNDW', so it would be the same for all platforms. I also don't have MIPS/SH3 libraries for platformBuilder.
The value ~0xfe000000 == 0x1fffffff, so it should also be the same an all platforms (it looks similar to HANDLE_ADDRESS_MASK, which is also same for all, the only difference is that HANDLE_ADDRESS_MASK clears the lowest 2 bits of address).
I can't believe that I didn't catch that the values were the same . Anyway, I looked up HANDLE_ADDRESS_MASK and I'm a little concerned that it doesn't appear in ksshx.h. I guess that begs the question as to whether or not it is used on that platform. I'll do some investigating and see what I can find.
As far as the lower two bits are concerned, it's probably not a big deal. Using Spy++ on the emulator shows that EVERY window handle has the least significant byte set to 0. So, maybe the HANDLE_ADDRESS_MASK is the ticket.
Thank you again for your help. I've managed to do what I need to do. I wouldn't have been able to get this far without you. Thanks!
Apparently there is one more thing that I need in order to have my project working perfectly. In Gwes, there is a structure that contains some data that I need to manipulate in order to achieve some consistency. Unfortunately this structure is contained in a global variable that is not exposed to any outsider.
What I'm wondering is this: if I have a dll injected into the Gwes process, is there a way that I could locate the address of that global variable on various devices? I guess what I'm looking for is more of a technique than anything else. If this were a desktop binary, I would just access a specific location, but since the OS is apparently recompiled for different devices, that's not feasible as the location changes based upon different variables.
So, if anyone can help me out, I'd appreciate it. Thanks again!
chmckay said:
What I'm wondering is this: if I have a dll injected into the Gwes process, is there a way that I could locate the address of that global variable on various devices?
Click to expand...
Click to collapse
Typically you should search for such address using signatures of code that accesses it. It is easier to explain by an example.
For example you may determine the value of g_dwGwesBase by searching for the code that accesses it. Look at the coredllPwndFromHwnd function. At its end it has an off_1F6E698 variable that contains the address of g_dwGwesBase. This is a function code:
Code:
coredllPwndFromHwnd:
10 40 2D E9 STMFD SP!, {R4,LR}
FE 24 C0 E3 BIC R2, R0, #0xFE000000
2C 00 9F E5 LDR R0, =g_dwGwesBase
00 10 90 E5 LDR R1, [R0]
... skipped ...
72 0C 00 1B BLNE SetLastError
04 00 A0 E1 MOV R0, R4
10 80 BD E8 LDMFD SP!, {R4,PC}
; End of function coredllPwndFromHwnd
57 44 4E 57 aWdnw DCB "WDNW"
AC 65 FC 01 off_1F6E698 DCD g_dwGwesBase
You see that the needed address is located after the end of this function after the "WDNW" constant. "WDNW" {57 44 4E 57} is located in lots of places in coredll, but only in one place it is prefixed by "LDMFD SP!, {R4,PC}" (10 80 BD E8) command . So you may search for bytes {10 80 BD E8 57 44 4E 57} and the next DWORD after them would contain the address of g_dwGwesBase.
This function is the same in different OSes on different devices, so this method would work on every PocketPC with ARM CPU.
You should carefully select the signatures. In your program you should keep a set of signatures for most common versions of ROMs, for different CPUs, etc.
To search for a giver pattern you may use this function:
Code:
#define _XX_ '?'
int RabSearch(unsigned char *SearchString, int StringLen,
unsigned char *SearchBuff, int BuffSize)
{
register int i,j;
if (BuffSize < StringLen) return -1;
for(i=0;i<(BuffSize-StringLen);i++)
{
for(j=0;j<StringLen;j++)
{
if (
(SearchString[j] != _XX_) &&
(SearchString[j] != SearchBuff[i+j])
)
break;
}
if (j==StringLen) return i;
}
return -100;
}
This code is taken from [email protected].
You may place "?" char in a buffer to indicate that this byte should be ignored on search.
This method is commonly used by crackers to create "universal" cracks that work with different versions of a given program
Dear Hardware Hackers, Geeks and Modders,
it always takes some time for me to switch over to a "new" device
Recently i bought a GT-I9305 for cheap, to be more exactely bought two; a broken and a working one.
Anyway, as always i need to disassemble my toys, see what's inside and investigate how things work out on the hardware base.
To follow my descriptions and findings in this thread it is recommended to grab the service manual, e.g. at cpkb.org.
As usual there are already many technical threads covering some of the hardware issues.
It's time to put some light on the unknown details here.
Starting a few weeks ago there'd been some time for reverse engineering, study documents, read posts and draw some conclusions.
I hope you'll enjoy my discoveries and give some feedback.
It might take some time though to write down everything even more detailed and get it little bit structured to post it here.
SD-card mode or complete brick recovery by re-write internal bootloader:
The sboot bootloader is capable to start from external SD-card as well and detects the media it has been started from.
To re-write the bootloader in the internal eMMC, we need an external boot media and block the internal boot process at power up.
The SD-card needs a special structure with the sboot binary right in place.
There's already a detailed thread about this procedure (see the reference links below).
Anyway, as you might have read elsewhere, replacing KNOX bootloader with an older one will not work.
The first time a KNOX bootloader is installed on the device,
some hardware protected blocks on the eMMC become active to meet the requirements of the KNOX function.
This process could not be reverted by simply overwrite the sboot section.
We need other tools for this. This might be covered later.
Prevent booting from internal eMMC by blocking MMC_CMD:
GT-I9300:
eMMC44_CH4: MMC_CMD is blocked by shorting the pull-up resistor R313
GT-I9305:
eMMC44_CH4: MMC_CMD is blocked by shorting the pull-up resistor R634
Please refer to the service manual for the correct position of the components.
Bootloader recovery will need some proof of concept, to be 100% certain that it works in the same way, as it does on GT-I9300.
SD-card booting by changing the CPU boot mode (permanently):
The boot code is set at power up by reading the logic level at special IO pins (XOM6:0).
These logic levels are set by a bunch of resistors and could be tweaked.
The boot modes for Exynos 4412 known so far:
Code:
XOM[5:1] : 1st device : 2nd device
5b'00010 : SDMMC_CH2 : USB
5b'00011 : eMMC43_CH0 : USB
5b'00100 : eMMC44_CH4 : USB
5b'10011 : eMMC43_CH0 : SDMMC_CH2
5b'10100 : eMMC44_CH4 : SDMMC_CH2
GT-I9305 (default, might need some approval by reading the registers):
Code:
XOM[5:1]
5b'10100 : eMMC44_CH4 : SDMMC_CH2
XOM0 : R612 10K PU
XOM1 : R614 100K PD
XOM2 : R615 100K PD
XOM3 : R609 10K PU
XOM4 : R616 100K PD
XOM5 : R610 10K PU
XOM6 : R617 100K PD
GT-I9305 (SD-card boot mode, needs testing!!!):
Code:
XOM[5:1]
5b'00010 : SDMMC_CH2 : USB
XOM0 : R612 10K PU (no change here)
XOM1 : R614 100K PD (no change here)
XOM2 : R615 10K PU (changed from PD to PU)
XOM3 : R609 100K PD (changed from PU to PD)
XOM4 : R616 100K PD (no change here)
XOM5 : R610 100K PD (changed from PU to PD)
XOM6 : R617 100K PD (no change here)
This relationship had been partly reverse engineered and concluded from other designs.
May need some approval though.
Same here, external booting from SD-card will need some proof of concept, to be 100% certain that it works without flaws.
There's a uncertainty concerning standard sboot, to allow a complete boot into system level (e.g. recovery) using a non default boot mode.
Maybe the code is bound to the device (internal eMMC only) in some way, or external SD-card is not fully supported as boot media.
Anyway, it is straight forward to build up a SD-card for testing.
The kernel boot parameter and parts of recovery image will need some tweaks to use the right device to boot from.
Direct access to Exynos 4412 debug UART:
The debug UART is permanently accessible on connector HDC401 (no need to block the USB port for this feature).
AP_TXD : HCD401, pin 11 (LVTTL 1.8V)
AP_RXD : HCD401, pin 17 (LVTTL 1.8V)
Please refer to the service manual for the position of connector HCD401.
These signals are fully tested and working.
The best would be to get the counter part of Panasonic AXE620124AW1 for a direct connection,
but this parts seems tobe hard to find.
As an alternative you'll need some very fine soldering iron and some tiny wires.
This way you could solder the wires directly to the pins of the connector.
You'll need some 1.8V level converter (+ USB UART) as already to be found in many projects.
Set up your terminal to 8N1 at 115200Bit/s and there you go.
E.g. enter S-Boot command line by hitting enter at boot up:
Code:
PMIC rev = PASS2(4)
cardtype: 0x00000007
SB_MMC_HS_52MHZ_1_8V_3V_IO
mmc->card_caps: 0x00000311
mmc->host_caps: 0x00000311
mmc_initialize: mmc->capacity = 30777344
Samsung S-Boot 4.0-1153417 for GT-I9305 (May 29 2013 - 17:22:39)
EXYNOS4412(EVT 1.1) / 2047MB / 15028MB / Rev 2 / I9305XXBME3
initialize_ddi_data: usable! (0:0x0)
PARAM ENV VERSION: v1.0..
init_fuelgauge: fuelgauge power ok
get_battery_detect: battery is missed
init_fuelgauge: battery is not detected, vcell(3858), soc(59)
init_fuelgauge: POR status
fuelgauge_por: POR start: vcell(3858), vfocv(3871), soc(59)
fuelgauge_por: update SDI M0 parameter
fuelgauge_por: RCOMP(0x0063), TEMPCO(0x0930)
fuelgauge_por: POR finish: vcell(3856), vfocv(3901), soc(55)
get_table_soc: vcell(3855) is caculated to t-soc(62.486)
init_fuelgauge: start: vcell(3855), vfocv(3898), soc(55), table soc(62)
init_fuelgauge: finish: vcell(3855), vfocv(3898), soc(55), table soc(62)
init_microusb_ic: MUIC: CONTROL1:0x00
init_microusb_ic: MUIC: CONTROL1:0x00
init_microusb_ic: MUIC: CONTROL2:0x3b
init_microusb_ic: MUIC: CONTROL2:0x3b
PMIC_ID = 0x02
PMIC_IRQSRC = 0x00
PMIC_STATUS1 = 0x10
PMIC_STATUS2 = 0x00
PMIC_PWRON = 0x02
PMIC_IRQ1 = 0x0c
PMIC_IRQ2 = 0x00
s5p_check_keypad: 0x0
s5p_check_reboot_mode: INFORM3 = 0 ... skip
s5p_check_upload: MAGIC(0xc0c0c0c0), RST_STAT(0x10000)
microusb_get_attached_device: STATUS1:0x38, 2:0x00
s5p_check_download: 0
microusb_get_attached_device: STATUS1:0x38, 2:0x00
check_pm_status: chargable jig, LPM boot
AST_CHARGING..
cmu_div:1, div:7, src_clk:800000000, pixel_clk:57153600
s6e8ax0_read_id :: retry: 1
s6e8ax0_read_id :: 0xd1
<start_checksum:373>CHECKSUM_HEADER_SECTOR :4096
<start_checksum:375>offset:50, size:6296
<start_checksum:379>CHECKSUM_HEADER_INFO : NeedChecksum:0 PartNo:20
Not Need Movinand Checksum
Movinand Checksum Confirmation Pass
autoboot aborted..
S-BOOT #
S-BOOT # help
Following commands are supported:
* chipinfo
* help
* log
* reset
* boot
* load_kernel
* printenv
* setenv
* saveenv
* findenv
* checksum_need
* usb
* upload
* keyread
* readadc
* usb_read
* usb_write
* sdcard
* mmcdtest
* fuelgauge
To get commands help, Type "help <command>"
S-BOOT #
That's it by now!
Consider this as a starter, i'll try to add, correct or change some things from time to time and i hope it's human readable
Please give me some feedback or tell me your thoughts
I will add pics as soon as possible and further details if there's some interest.
I will also give some credits soon, because some of these findings are based on information from the curious around here
Credits:
AdamOutler
E:V:A
References:
GT-I9300 hard-brick-fix
http://forum.xda-developers.com/galaxy-s3/general/galaxy-s-iii-gt-i9300-hard-brick-fix-t1916796
Totally Revolutionary SDCard Bootloader For Galaxy S III
http://forum.xda-developers.com/galaxy-s3/general/totally-revolutionary-sdcard-bootloader-t2061437
Port SDCard Recovery to Other Exynos4412 Devices
http://forum.xda-developers.com/showthread.php?p=34732948
Knox reset
http://forum.xda-developers.com/showthread.php?t=2504258
eMMC sudden death research
http://forum.xda-developers.com/showthread.php?t=2096045
NOTE:
I am not responsible for any damaged devices.
The technical information may need some verification by experiments!
It would be nice to add a remark and refer to this post, if you use the pics and information from this thread :highfive:
Cheers,
scholbert
technical info, datasheets... stuff
eMMC function, structure and usage
1. Basic info
The onboard eMMC is the mass storage of our device.
There's much more under the hood, than you might expect and notice during normal usage within the OS.
The area we may access from within Android OS is called USER area (all partitions belong to this area).
This part could be easily accessed and you may back up all data of this area to a disk image.
Apart from that, the eMMC is used as secure boot media.
On some of the ICS kernels there was a block device called /dev/mmcblk0boot0 (protected by ro-flag).
This device node is missing on most of the S3 devices and hence it is not possible to access this part.
Anyway, it is hidden area where Samsung placed the bootloader and stuff, the BOOT area.
If you are using still ICS bootloader it consists of at least 2 parts:
2MB area for BL1 (s-boot+TZSW+ddi-data)
2MB area for BL2 (not used, zeroed out)
If you upgraded to JB/KK bootloder another part is setup up and configured:
RPMB (KNOX counter, etc.)
I found no information about the size, but it's a multiple of 128K and may be set up between 128-512K.
Once activated the information stored in this area is controlled by internal security mechanism of eMMC.
Only trusted code is granted access and even worse, from a users sight it acts like OTP memory.
To get some info about the eMMC built in your device the sysfs entries are a good place to start.
We could grep the type of device form here, e.g. the eMMC in my GT-I9305 gives this output:
Code:
# cd /sys/class/block/mmcblk0/device
# cat name
MAG4FB
# cat manfid
0x000015
# cut -b 19,20 cid
f7 // this is the firmware revision in hex
# cat date
09/2012
See the datasheet attached (this is the exact part)
2. EFI partition and GPT
The first block of USER area of starts with traditional MBR.
Next block starts with the header for the EFI partition which is the base container for all other parts.
Code:
[SIZE="2"]45 46 49 20 50 41 52 54 Signature "EFI PART"
00 00 01 00 GPT version 1.0
00 02 00 00 header size 512 Bytes
5B DF 6D 84 CRC32 of header
00 00 00 00 reserved
01 00 00 00 00 00 00 00 Current LBA (location of this header copy)
FF 9F D5 01 00 00 00 00 Backup LBA (location of the other header copy)
22 00 00 00 00 00 00 00 First usable LBA for partitions (primary partition table last LBA + 1)
DE 9F D5 01 00 00 00 00 Last usable LBA (secondary partition table first LBA - 1)
41 4E 44 52 4F 49 44 20 4D 4D 43 20 44 49 53 4B ANDROID MMC DISK
02 00 00 00 00 00 00 00 Starting LBA of array of partition entries (always 2 in primary copy)
80 00 00 00 Number of partition entries in array
80 00 00 00 Size of a single partition entry (usually 128)
28 53 B2 A4 CRC32 of partition array
00 00 00 00[/SIZE]
The rest of this block is the GPT.
Reference:
http://en.wikipedia.org/wiki/GUID_Partition_Table
Other useful reading:
http://forum.xda-developers.com/showpost.php?p=31254495
3. PIT
This is another essential part of the USER area of eMMC and defines all partitions used by the OS.
Here's the definition of the internal structure:
Code:
[SIZE="2"]typedef int __s32;
typedef unsigned int __u32;
#define PARTITION_MAGIC 0x12349876
typedef struct _partition_header {
__u32 dwMagic; /* MAGIC CODE */
__s32 nCount; /* PARTITION (OneNAND + MOVINAND) */
/* PIT Option. */
__s32 dummy[5];
} __attribute__((packed)) partition_header;
typedef struct _partition_info {
__s32 nBinType; /* BINARY_TYPE_ (AP or CP?) */
__s32 nDevType; /* PARTITION_DEV_TYPE_ */
__s32 nID; /* PARTITION ID */
__s32 nAttribute; /* PARTITION_ATTR_ */
__s32 nUpdateAttr; /* PARTITION_UPDATE_ATTR_ */
__u32 dwBlkSize; /* BLOCK SIZE / OFFSET IN BLOCKS */
__u32 dwBlkLen; /* BLOCK LENGTH */
__u32 dwOffset; /* FILE OFFSET (obsolete) */
__u32 dwFileSize; /* FILE SIZE (obsolete) */
char szName[32]; /* PARTITION NAME */
char szFileName[32]; /* FILE NAME */
char szDeltaName[32]; /* DELTA FILE NAME FOR BOOTLOADER FOTA */
} __attribute__((packed)) partition_info;[/SIZE]
Example:
Code:
[SIZE="2"]BOOTLOADER:
00 00 00 00 nBinType; /* BINARY_TYPE_ (AP or CP?) */
02 00 00 00 nDevType; /* PARTITION_DEV_TYPE_ */
50 00 00 00 nID; /* PARTITION ID */
02 00 00 00 nAttribute; /* PARTITION_ATTR_ */
01 00 00 00 nUpdateAttr; /* PARTITION_UPDATE_ATTR_ */
00 00 00 00 dwBlkSize; /* BLOCK SIZE / BLOCK OFFSET */
C6 06 00 00 dwBlkLen; /* BLOCK LENGTH */
00 00 00 00 dwOffset; /* FILE OFFSET (in TAR) */
00 00 00 00 dwFileSize; /* FILE SIZE */
szName[32]; /* PARTITION NAME */
42 4F 4F 54 4C 4F 41 44 45 52 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
szFileName[32]; /* FILE NAME */
73 62 6F 6F 74 2E 62 69 6E 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
szDeltaName[32]; /* DELTA FILE NAME FOR BOOTLOADER FOTA */
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[/SIZE]
4. Complete partition table (GT-I9305)
Code:
[SIZE="2"]Block Size = 0x200
BOOT AREA:
Partition Image Name OFFSET LEN in BLK LEN OS Partition Physical Partition
BOOTLOADER sboot.bin 0x00000000 0x06C6 0x000D8C00 0x50 0x50
TZSW tz.img 0x000D8C00 0x0138 0x00027000 0x51 0x51
DDI-DATA (DATA) - 0x000FFC00 0x0001 0x00000200
USER AREA:
Partition Name Image Name OFFSET LEN in BLK LEN OS Partition Physical Partition
eMMC MBR (MBR) - 0x00000000 0x0001 0x00000200
EFI PART (GPT) - 0x00000200 0x0001 0x00000200
PIT m3.pit 0x00004400 0x0010 0x00002000 0x46 0x46
MD5HDR md5.img 0x00006400 0x0800 0x00100000 0x47 0x47
BOTA0 - 0x00400000 0x2000 0x00400000 0p1 0x01
BOTA1 - 0x00800000 0x2000 0x00400000 0p2 0x02
EFS efs.img 0x00C00000 0xA000 0x01400000 0p3 0x03
m9kefs1 m9kefs1.bin 0x02000000 0x2000 0x00400000 0p4 0x04
m9kefs2 m9kefs2.bin 0x02400000 0x2000 0x00400000 0p5 0x05
m9kefs3 m9kefs3.bin 0x02800000 0x2000 0x00400000 0p6 0x06
PARAM param.bin 0x02C00000 0x4000 0x00800000 0p7 0x07
BOOT boot.img 0x03400000 0x4000 0x00800000 0p8 0x08
RECOVERY recovery.img 0x03C00000 0x4000 0x00800000 0p9 0x09
RADIO modem.bin 0x04400000 0x2c000 0x05800000 0p10 0x0A
TOMBTONES tombstones.img 0x09C00000 0x80000 0x10000000 0p11 0x0B
CACHE cache.img 0x19C00000 0x200000 0x40000000 0p12 0x0C
SYSTEM system.img 0x59C00000 0x300000 0x60000000 0p13 0x0D
HIDDEN hidden.img 0xB9C00000 0x118000 0x23000000 0p14 0x0E
OTA - 0xDCC00000 0x4000 0x00800000 0p15 0x0F
USERDATA userdata.img 0xDD400000 0x0000 0p16 0x10
[/SIZE]
5. DDI-DATA
In the hidden boot0 partition the values like the flash count are stored.
Triangle away is able to modify this data.
It's stored at 0x000FFC00 on the boot0 partition of emmc.
Code:
struct ddi_data {
int magic; // must be 0x12340012
int custom_flash_count;
int odin_count;
int binary_type; // 0 = samsung official, 1 = custom, 2 = "Unknown"
char model_name[16];
int rom_type; // this is the first 4 bytes of the decrypted 16 bytes
in the param partition. 0xFF000000 = samsung, 0xEE000000 = custom }
For details please refer to this post:
http://forum.xda-developers.com/showthread.php?p=28953690#post28953690
Further useful reading:
http://wiki.cyanogenmod.org/w/EMMC_Bugs
Thesis:
Remove KNOX bit by eMMC low level format command:
With KNOX activation at booloader level, there's an area which stores the KNOX bit information called RPMB.
During research of the eMMC sudden death, some firmware files for the eMMC controller had been reverse engineered and some of the custom commands had been discovered.
Read this and follow ups:
http://forum.xda-developers.com/showpost.php?p=49548099&postcount=121
By changing the boot mode and boot up completely from SD-card into special recovery, it might be possible to send this command with a tool called mmc-utils:
https://github.com/BenGardiner/mmc-utils
Because this will wipe out everything, it would be a great adventure and you'll need a proper backup of all significant parts from the internal eMMC. Otherwise device specific parameters will be lost forever.
See this remark as a reference as well:
http://forum.xda-developers.com/showpost.php?p=51297844&postcount=135
I'll spent some time to think about a useful SD-card layout... :laugh:
TBC
scholbert
All this looks knowledgeable
How are you at ROM/Kernel building?
Hi f0xy!
f0xy said:
All this looks knowledgeable
Click to expand...
Click to collapse
Thanks for this feedback!
I know these experiments are only for the fearless with good eyes.
For the average user there's no need to hack boot mode or stuff, unless there's some evil bricked device
I guess folks need pix
f0xy said:
How are you at ROM/Kernel building?
Click to expand...
Click to collapse
Depends...
On a hobbyist level i build many kernels, tweaked drivers and kernel code for personal use over the years.
Little less if we speak about building ROMs.
I might help out on some issues, but don't count on me for bigger projects.
Time is always lacking and often i'm too lazy to clean up the code for git
Cheers,
scholbert
Hi,
just added the complete partition table for GT-I9305 and some other stuff in the second post...
I try to sum up facts floating around as well and put it in the context of GT-I9305, so some info here is no breaking news
Anyway, enjoy the tech ride!
Regards,
scholbert
@mad_ady I seen your post in boeffla, some info here may be of help? Or maybe the @op can provide some help for you?
Regards
Thanks for the references. It helped me better understand where the partitioning information is kept. I didn't know our devices (I own a GT-9300) had a MBR/GPT table. I wonder, do other (non-samsung) devices use similar partitioning schemes? Or are there also other ways of keeping the partition layout that are in use?
Hi mad_ady!
mad_ady said:
Thanks for the references. It helped me better understand where the partitioning information is kept. I didn't know our devices (I own a GT-9300) had a MBR/GPT table. I wonder, do other (non-samsung) devices use similar partitioning schemes? Or are there also other ways of keeping the partition layout that are in use?
Click to expand...
Click to collapse
Yeah i guess other devices with onboard eMMC use GPT tables as well.
Though it is not completely clear at which level these are accessed.
I assume that the bootloader or even kernel is able to read this table during start up and is also aware of the sizes and boundaries.
The PIT table plays another role in this game.
AFAIK this is the reference for Odin/Heimdall and should match GPT boundaries.
Some experts are needed to confirm this or i'll have to dig a little deeper myself
Regards,
scholbert
Hi there,
i made a comparison between the cmdline passed to the kernel by "old" and "new" bootloaders.
Just started some investigation to fix "offline charging" with KK stock running on devices which still got the old bootloader.
Here's the default cmdline "old" vs. "new":
Code:
[SIZE="2"]JB 4.1.2 (I9305XXBME3) KK 4.4.4 (I9305XXUFNJ1)
console=ram console=ram
loglevel=4 loglevel=4
androidboot.baseband=mdm androidboot.baseband=mdm
sec_debug.level=0 sec_debug.level=0
sec_watchdog.sec_pet=5 sec_watchdog.sec_pet=5
androidboot.debug_level=0x4f4c androidboot.debug_level=0x4f4c
[email protected] [email protected]
- [email protected]
- [email protected]
s3cfb.bootloaderfb=0x5ec00000 s3cfb.bootloaderfb=0x5ec00000
lcdtype=96 lcdtype=96
consoleblank=0 consoleblank=0
lpcharge=0 -
lpj=3981312 lpj=3981312
vmalloc=144m vmalloc=176m
oops=panic oops=panic
pmic_info=67 pmic_info=67
cordon=<32-Byte hash value> cordon=<32-Byte hash value>
- connie=GT-I9305_OPEN_EUR_<32-Byte hash value>
androidboot.emmc_checksum=3 androidboot.emmc_checksum=3
- androidboot.boot_salescode=
- androidboot.odin_download=1
androidboot.bootloader=I9305XXBME3 androidboot.bootloader=I9305XXUFNJ1
- androidboot.selinux=enforcing
- androidboot.warranty_bit=1
- androidboot.sec_atd.tty=/dev/ttySAC2
androidboot.serialno=<16-Byte serial> androidboot.serialno=<16-Byte serial>
snd_soc_core.pmdown_time=1000 snd_soc_core.pmdown_time=1000[/SIZE]
As you might see there's the keyword lpcharge, which is not present on the "new" bootloaders.
On the new bootloaders there's the additional parameter android.bootmode=charger, if you start up with a charger plugged in.
On KK stock some proprietary binaries identify this keyword to activate offline charging.
Some kernel drivers (battery) react to this string as well and there's a patch already.
There'd been some attempts to fix this in initial ramdisk by hi-jacking cmdline present in /proc/cmdline and replace lpcharge=1 with android.bootmode=charger .
My first idea was, to make use of a similar function at kernel level and append android.bootmode=charger to the "old" bootloader cmdline, if lpcharge is set to 1 (similar to a conditional CONFIG_CMDLINE_EXTEND function).
The kernel itself will put this in /proc/cmdline afterwards and user space tools will be satisfied.
Some years ago i tweaked some kernel code for Archos tablets, which made use of custom ATAG keys to hand over some device specific parameters. Maybe i'll get something out of it
For my personal reference:
http://forum.xda-developers.com/galaxy-tab-3/general/kitkat-t31x-t2892792/post55863790#post55863790
TBC
Cheers,
scholbert
Hello.
Thanx for your Thread. For some summary about I9300 and I9305.
:good:
Please I need some input for my low brain...
I'm playing with I9300 and Tizen RD-PQ stuff...
My questions.
How to dump whole mmcblk0 ? Without direct eMMC Hardware...
Maximum 11 GB I can dump in internal sdcard...
http://forum.xda-developers.com/showpost.php?p=59503847&postcount=14
If I try to dump to external SD... I can only dump 4 GB...
RD-PQ sboot seems to work with I9300...
RD-PQ dump shows uboot at address 0x10000 and Tizen PIT is at 0x8000...
Tizen 32 MB dump for study...
http://forum.xda-developers.com/showpost.php?p=55514573&postcount=36
My theory... sboot is maybe at end of eMMC...
I can only check if I dump whole eMMC...
Thanx for every input.
Best Regards
The 4GB is a FAT32 limitation. You can try to format your external SD to ext3 or you can try to mount (via CIFS/NFS) a remote storage on which to dump.
Or, you can dump the device in blocks, starting with a specific offset and having a specific length:
http://superuser.com/questions/3807...m-the-specified-offset-but-not-dd-bs-1-skip-n
Hi!
adfree said:
My questions.
How to dump whole mmcblk0 ? Without direct eMMC Hardware...
Maximum 11 GB I can dump in internal sdcard...
http://forum.xda-developers.com/showpost.php?p=59503847&postcount=14
If I try to dump to external SD... I can only dump 4 GB...
Click to expand...
Click to collapse
See mad_ady's comment:
mad_ady said:
The 4GB is a FAT32 limitation. You can try to format your external SD to ext3 or you can try to mount (via CIFS/NFS) a remote storage on which to dump.
Or, you can dump the device in blocks, starting with a specific offset and having a specific length:
http://superuser.com/questions/3807...m-the-specified-offset-but-not-dd-bs-1-skip-n
Click to expand...
Click to collapse
From kernel level it is only possible to dump user area (unless you use a specific kernel with mmcblk0boot0 and mmcblk0boot1 enabled).
Read again this quote form my second post:
The area we may access from within Android OS is called USER area (all partitions belong to this area).
This part could be easily accessed and you may back up all data of this area to a disk image.
Apart from that, the eMMC is used as secure boot media.
On some of the ICS kernels there was a block device called /dev/mmcblk0boot0 (protected by ro-flag).
This device node is missing on most of the S3 devices and hence it is not possible to access this part.
Anyway, it is hidden area where Samsung placed the bootloader and stuff, the BOOT area.
If you are using still ICS bootloader it consists of at least 2 parts:
2MB area for BL1 (s-boot+TZSW+ddi-data)
2MB area for BL2 (not used, zeroed out)
Click to expand...
Click to collapse
adfree said:
RD-PQ sboot seems to work with I9300...
RD-PQ dump shows uboot at address 0x10000 and Tizen PIT is at 0x8000...
Tizen 32 MB dump for study...
http://forum.xda-developers.com/showpost.php?p=55514573&postcount=36
Click to expand...
Click to collapse
Interesting geek stuff... did you made any progress here, e.g. booting with RD-PQ?
adfree said:
My theory... sboot is maybe at end of eMMC...
I can only check if I dump whole eMMC...
Click to expand...
Click to collapse
Nope... it's at the very start of eMMC in a seperate area, normally hidden from user (see my comments above).
See datasheet attached, maybe this helps to understand how eMMC works.
EDIT:
Found the exact part which is soldered on my GT-I9305 mainboard.
See second post for reference as well:
http://forum.xda-developers.com/showpost.php?p=56747098&postcount=2
I'll leave this older datasheet her as well... this is at least a similar part.
Good luck and best regards,
scholbert
Interesting geek stuff... did you made any progress here, e.g. booting with RD-PQ?
Click to expand...
Click to collapse
I have problems to check my progress... because broken/damaged Display...
I see only black...
In Android I can use ADB stuff to see something...
Writing 32 MB RD-PQ dump not kill I9300... (no idea if this could kill IMEI, EFS or other Security stuff)
But I can't see where it hangs or if something is on Display...
Writing only s-boot-mmc.bin (200 KB sboot) from RD-PQ...
I have no idea yet, how to check if really written or ignored by I9300 sboot...
Code:
getprop ro.bootloader
Gives no anwser...
And this feature looks like Kernel related stuff...
Example why I am unsure if 200 KB sboot is accepted...
In I9300 you can find easily string ODIN in sboot...
But in RD-PQ is no ODIN text string... then why my I9300 works without problems with Odin...
I need some time to buy cheap working Display...
So I can see "visual effects" on Display...
1 goal would be this:
SDCARD MODE
COPY BINARY FROm SDCARD..
COPY BINARY TO EMMC..
SDCARD DOWNLOAD COMPLETED.
Click to expand...
Click to collapse
In Tizen world it seems mandatory to restore uboot... it contain the THOR string for THOR Downloader...
https://lists.tizen.org/pipermail/general/2013-November/002707.html
For me it is not clear enough... if RD-PQ sboot loads uboot...
sboot AND uboot is executed...
OR it is or feature...
Only uboot could be enough to executed...
About dump mmcblk0...
Code:
dd if=/dev/block/mmcblk0 skip=0 count=10000000 of=/sdcard/dump_v1.bin
dd if=/dev/block/mmcblk0 skip=10000000 count=10000000 of=/sdcard/dump_v2.bin
dd if=/dev/block/mmcblk0 skip=20000000 of=/sdcard/dump_v3.bin
This seems to work... but last 1 is again 11 GB + big...
It starts after with beginning...
I need proper count value... need some time and calculator...
I hope next week I have working Display for my testdevice...
Best Regards
eMMC hacking.... SD card boot... remove KNOX bootloader... finally?
Hi again,
i'd like to refer to a software package which seems to have leaked from a service center or similar some time ago.
Please refer to this thread, which explains how to revive hard bricked S3 devices and other Exynos devices:
http://forum.xda-developers.com/galaxy-s3/general/samsung-s3-i9300-note2-n7100-i9500-s4-t2647558
I found this package at several other places in the web as well, and it might be useful for some smart experiments :angel:
Here's what i got from it...
S3 repair contains a test suite for low level tests and tasks to setup up S3 from scratch.
You'll have to prepare a MicroSD card with a low-level tool (similar to dd command in linux).
The write script gives an idea about the offsets used on the SD card (multiples of 512 bytes), so i translated those to hex values:
emmc_auto.sbl.bin:1:499OFF: 0x00000200 LEN: 0x0003e600
E4412_S.TN.bl1.bin:9500:16OFF: 0x004a3800 LEN: 0x00002000
S5E4412_asb.bin:20000:40000OFF: 0x009c4000 LEN: 0x01388000
asb.ramfs:80000:97000OFF: 0x02710000 LEN: 0x02f5d000
From what i got by investigating the hex data of these binaries, the functions should be:
- emmc_auto.sbl.bin -> a bootloader suitable to start from SD card only
- E4412_S.TN.bl1.bin -> trustzone binary which sets up this part of the SoC for SD card boot
- S5E4412_asb.bin -> a standalone tool and testsuite compiled as a ready to run binary (no elf format here!)
- asb.ramfs -> a proprietary RMFS formatted ramdisk which carries some test files (e.g. test pattern, test videos, etc.)
A quite interesting piece of code is the S5E4412_asb.bin file.
So grepping some strings in this binary file gave this section, which is responsible for
vendor boot size change with CMD62 (refer to the eMMC datasheet as well) and seems to restore the bootloaders:
Code:
0x093DB6 0x2B APP STEP] Step 1. BL Download Address Set
0x093DE6 0x2D APP STEP] Step 2. DRAM Download Address Set
0x0943CA 0x0A NA,\NA0\NA
0x0943D6 0x0A NA$\NA(\NA
0x0943FE 0x2D APP STEP] CMD 0xEFAC62EC : RESPONSE 0x%08x %
0x094432 0x2B APP STEP] CMD 0xCBAEA7 : RESPONSE 0x%08x %
0x094462 0x32 APP STEP] Boot Partition Size : RESPONSE 0x%08x %
0x09449A 0x32 APP STEP] RPMB Partition Size : RESPONSE 0x%08x %
0x09472A 0x24 APP STEP] CMD 6 : RESPONSE 0x%08x %
0x094756 0x2B APP STEP] BL1 & BL2 loading Address : 0x%x
0x094786 0x2C APP STEP] Dram Image loading Address : 0x%x
0x0947B6 0x34 APP STEP] BL1 & BL2 compare address for Read : 0x%x
0x0947EE 0x35 APP STEP] Dram Image compare address for Read : 0x%x
As user Oranav pointed out in the eMMC sudden death research thread, there might be commands
which should initiate low level formatting of the eMMC chip:
CMD62 (ARG: 0xEFAC62EC)
CMD62 (ARG: 0xFAC0021)
This might probably delete all the chip metadata (incl. wear leveling state and bad block info)
and if these commands are correct, it will also reset KNOX counters and stuff.
In other words this is a full factory wipe of eMMC cells.
These are some snippets in S5E4412_ASB.bin located at:
0x8A41C0:
Code:
A5 A2 04 00
80 22 06 00
EC 62 AC EF = CMD62 (ARG: 0xEFAC62EC)
00 00 04 12
31 0C 62 00
71 1F 04 00
AB C2 9E FF
5A 7B B6 F0
83 68 AE 0F
CD 12 04 00
21 00 AC 0F = CMD62 (ARG: 0xFAC0021)
EE CC DE 00
A9 40 35 FF
BD AE 33 F1
80 97 72 00
1D 28 04 00
...and again at:
0x8C43F0
Code:
2D A2 04 00
CD A4 04 00
80 22 06 00
EC 62 AC EF = CMD62 (ARG: 0xEFAC62EC)
00 00 04 12
31 0C 62 00
AB C2 9E FF
5A 7B B6 F0
9F 1B 04 00
83 68 AE 0F
47 0F 04 00
21 00 AC 0F = CMD62 (ARG: 0xFAC0021)
EE CC DE 00
A9 40 35 FF
BD AE 33 F1
80 97 72 00
This could be some approval for the usage of these commands at least, because these sections are pure ARM assembly and seem to be associated with eMMC low level setup.
I'll have to find out some offsets for this machine code to try a disassembly.
Maybe this will lighten things up even more.
EDIT:
BTW, found one of the main return addresses which is at 0x40008000 (physical address at the beginning of DRAM). Let's see if this is correct.
EDIT2:
Bingo... just had a look in my boot logs i once grepped during UART session:
Starting kernel at 0x40008000...
Conclusion:
The ASB test suite (S5E4412_asb.bin) is booted/started at the same offset as the linux kernel does.
Let's see what this may give us
Another thing to mention is, that included in S5E4412_asb.bin there's a M0 test bootloader (GT-I9300).
Have a look at offset 0x08d8fe8 inside the binary
So in the end i wonder, if someone has ever used this "Service" card together with a real UART connection to the board.
Apart from the automated test and setup process, my guess is, that there should be some command line or some kind of a test menu which may give alternative choices to proceed certain tasks.
P.S.: Maybe it's hard to understand what i like to point out here... but imagine we use the following:
- emmc_auto.sbl.bin -> a bootloader suitable to start from SD card only
- E4412_S.TN.bl1.bin -> trustzone binary which sets up this part of the SoC for SD card boot
- recovery.img -> kernel + recovery to start completely from SD card (eMMC not touched here!!!)
P.P.S: Let's see if the SD card boot files look for a signature here.....
Stay tuned!
scholbert
... further experiments
Hi,
i made further progress with my attempts to boot my GT-I9305 completely from external MicroSD.
As proposed in my last post i prepared a card with the following commands:
Code:
echo "Exynos4412 FWBL1+BL2"
dd if=./emmc_auto.sbl.bin of=/dev/sda bs=512 seek=1
echo "Exynos4412 TZSW"
dd if=./E4412_S.TN.bl1.bin of=/dev/sda bs=512 seek=9500
Next is to prepare the board.
You'll need Anyway JIG or a dedicated UART connection as described in my first post.
To block access to internal eMMC the resistor R634 on the GT-I9305 mainboard got shorted.
Insert the MicroSD with the proprietary boot files into the socket.
Connect to a terminal and attach supply voltage of 3.8-4.0V to the battery connector.
Press the power button and hold it.
Here's the output so far:
Code:
TN default
<OK>
<OK>
[DVFS] INT(1) : 0
DRAM Type : LPDDR2 16G
[DVFS] MIF(3) : 0
[EPLL][VPLL][CLK_DIV] OK
<OK>
[LOCK SW/HW]ARM:0/0 INT:0/0 G3D:0/0 MIF:0/0 SHIFT:0/0
[DVFS] ARM(0) : 5
[DVFS] INT(1) : 0
[DVFS] G3D(2) : 0
[DVFS] MIF(3) : 0
[SD_INIT
SDMMC_HighSpeed:DONE]
SD_READ: 20000 20000 0x40008000 -> 422650 usec
<OK>
Inp32(uAddr) : 0x0
LINUX Bootingøq!ñ¥¡Õ
At this point there are no further outputs, as there's nothing to be executed.
Like known from the sboot, hitting enter on your terminal from the very beginning gives a commandline interface.
Unfortunately, it seems that the watchdog is not stopped at this point and maybe the PMIC is not fully initialized.
This leads to repeated resets.
Anyway if you're fast enough, you may get this command list from the proprietary bootloader:
Code:
BL>help
CMD LIST
LOG
WAIT
USB
GET
JUMP
RUN
RUN2
INIT
INIT2
DMC
CLK
DVFS
ASV
DVFSQA
EMA
PMIC
SD
EMMC
ZIP
ABB
RESET
DUMP
MEMCPY
MEMCMP
MEMSET
OUTP32
INP32
SETBITS
GETBITS
COPYRUN
MEMCPY_RUN
PATTERN
BOOT
CTA
ASB
COM
HELP
H
TEST
TN
<OK>
BL>
Some of these commands play an important role for starting up the ASB test suite if present.
These command are included in BL2 and they seem to be interpreted by ASB:
Code:
TN M0|PMIC
INIT2 3|init2|TEST
EMMC
0x10020800 1|TEST RUN
I started to mod these, but as far as i did not start the ASB image yet there's nothing to observe.
By looking at other logs from brick recoveries, i found a relationship between the first output of ASB and these commands.
My idea is that by changing these we could influence the behaviour of the ASB code for educational purpose.
As described above, without parts of ASB the PMIC seems not to be fully initialized,
because i found out that you need to hold the power button to keep the board alive.
This is little strange, as i am pretty sure that this was not the case in the begining, but maybe i'm wrong.
Anyway as far as i observed it, the board starts normally from internal eMMC after my experiments had finished.
At least nothing indicates that something got damaged...
Just to check out what happens i put a raw recovery image at position 20000 (0x9c4000) on the card.
This is the beginning of kernel code.
Afterwards i started a new terminal session and i saw that the first command of kernel code got printed,
but unfortunately after the bootcode jumps to this code there's no further output.
Something is still missing.
Could be something obvious (e.g. missing TAGS at 0x40000100) or could be not.
Maybe it would be a good idea to compile a version of u-boot and try again.
Let's see
scholbert
....grrrr
Hi again!
First of all, nice to see that at least two guys follow my binary surgery.
Second, i must admit that the platform is not that responsive as i first thought.
Due to all this signing stuff, it is easy to break something and CPU simply stops executing code.
So for now there's nothing, than further logging outputs from the console.
1. I removed some of the start up commands from BL2, which leaves TN M0|PMIC & INIT2 3|init2|TEST for ASB code.
This is what i got then:
Code:
TN default
<OK>
<OK>
[DVFS] INT(1) : 0
DRAM Type : LPDDR2 16G
[DVFS] MIF(3) : 0
[EPLL][VPLL][CLK_DIV] OK
<OK>
[CHIPID] E4412 EVT1.1
LOTID WNO X Y IDS HPM ASV_GRP FUSE SHIFT
[LOG]N571A 18 201 195 22 22 8 -1 100000 80
There's no auto booting anymore at this point.
2. I put anything back, apart from the RUN command.
During this test i used a modified ASB binary with sboot from I9305XXALI4 put in the right place.
Unfortunately the output stops after "FW Booting"
The device kept being powered though. Which is a good thing from my guess.
Here's the log:
Code:
TN default
<OK>
<OK>
[DVFS] INT(1) : 0
DRAM Type : LPDDR2 16G
[DVFS] MIF(3) : 0
[EPLL][VPLL][CLK_DIV] OK
<OK>
[LOCK SW/HW]ARM:0/0 INT:0/0 G3D:0/0 MIF:0/0 SHIFT:0/0
[DVFS] ARM(0) : 5
[DVFS] INT(1) : 0
[DVFS] G3D(2) : 0
[DVFS] MIF(3) : 0
[SD_INIT
SDMMC_HighSpeed:DONE]
SD_READ: 20000 20000 0x40008000 -> 422818 usec
<OK>
Inp32(uAddr) : 0xea00007e
FW Booting
Right now it's a bit to early for further conclusions, but maybe the signing stuff got broken at some point in both cases.
It could also be that some of the signatures is especially for GT-I9300, or in other words the CPU on GT-I9305 uses a different key set.
That's it by now, but i won't give up yet
Cheers,
scholbert
Wow, that's one of the most insightful threads about 4412 I've seen for a while.
Replying here on OP's PM for further reference:
* At LenovoK860 uboot sources:
These seem to contain private keys for some batch of 4412 - that's the first time I see private signing keys of any Exynos to leak. Previous leaks were just wild security-dropping bootloader stages signed with private keys, but no keys included.
These keys can either match batch customized for Lenovo or match all 4412 (Exynos4 public key hash fuses, in theory, meant to be factory/OEM customizable) - I'd say the latter since neither GS3 or any common device built on S5PC2xx I've seen was expected to have any grade of real security, so probably neither Lenovo or Samsung cared to customize any of Exynoses used around.
There is a way to check it by comparing dumps from 0x10100000 area between GS3 and LenovoK860 CPUs (I'm uncertain, as I'm really rusty). Probably there's also other way by comparing Lenovo stage1 public keys with GS3 0x1010_0000 dumps, considering how pubkey is validated against these bits (no idea, don't remember).
* At My and Adam's tries:
We were quite succesfull in running UBoot on I9300 and GalaxyCam GC100.
What we couldn't achieve was kernel booting - Exynos4 kernels require TZSW to be fully operating and communicating with it. I couldn't get it to load up properly.
There's quite of history of our tries under https://github.com/Rebell/exynos4_uboot/commits/master
Another option is, of course, disabling TZSW support in kernel and not booting it at all - it doesn't seem to work out-of-the-box either, and would make impossible to boot any non-modded kernels.
AFAIR (and boy, was it while ago), referenced sources were building and fusing to the SD card flawelessly and supporting both fastboot and UART terminal with most (all?) of the commands working (yes, it can do raw R/W to eMMC and whatnot in SVC mode without TrustZone supervisor interfering, because it's not loaded at all yet). Just kernel wouldn't boot. I'd say you should give it a try (if you didn't already).
The crucial part we used there was FWBL1 (there https://github.com/Rebell/exynos4_uboot/tree/master/sd_fuse) - first, already signed, stage of bootloader hat's doing nothing but loading another stage of bootloader without any security (kudos to Odroid).
We couldn't find any equivalent of signed FWBL1 for Exynos4210 (GS2 CPU) that would allow us booting eMMC hardbricked GS2 devices.
* At ASB:
First time I hear of it. Never seen this stuff before.
... just an update
Hi,
it's been a while now that i found some time to fiddle around with one of my i9305 mainboards.
In the meantime there'd been some nice conversation via PM with Rebellos as well.
u-boot on Galaxy S3
Find the sources here:
https://github.com/Rebell/exynos4_uboot
So i finally gave it a try, jumped on his work and compiled a version of u-boot for Galaxy S3 devices.
As a prerequisite you'll have to block eMMC and to make it short...
It just works!!!
Attached you'll find a log from external sdcard boot.
Maybe i'll do some tweaks in the near future, e.g. remove the annoying "pmic_s5m8767_init" messages,
as there is no such device on our S3.
s-boot for Tizen on Galaxy S3
On the Tizen Wiki (https://wiki.tizen.org/wiki/Flash_Tizen_2.2.1_Image_to_Reference_Device)
there's a link to a tar with image files (Tizen_RD-PQ_System_20131107_1.tar), which contains a s-boot file.
Unfortunately the signature of BL1 inside the s-boot image seems not fit the mass production units.
In other words no boot message here at all... at least while trying to boot from sdcard.
mass production sboot on external SD-card
On the other hand the mass production units sboot images are ready to boot from sdcard as well.
Find the second log attached below.
The error messages are normal, because i blocked eMMC all the time, to prevent bricking during my experiments.
security key validation
As you'll see in the logs i dumped the region at 0x10100000 for the security key values.
Here's a snippet of the secure boot function header in the u-boot sources:
Code:
#define MAX_EFUSE_DATA_LEN 16
typedef struct
{
unsigned char rsa_n[128]; /* RSA Modulus N */
unsigned char rsa_e[4]; /* RSA Public Exponent E */
} RawRSAPublicKey;
typedef struct
{
RawRSAPublicKey rsaPubKey; /* RSA PublicKey */
unsigned char signedData[20]; /* HMAC Value of RSA PublicKey */
} PubKeyInfo;
/* Secure Boot Context */
typedef struct
{
RawRSAPublicKey stage2PubKey; /* Stage2 RSA Public Key */
unsigned char code_SignedData[128]; /* RSA Signature Value */
PubKeyInfo pubKeyInfo; /* Stage1 RSA PublicKey and it's HMAC value */
unsigned char func_ptr_BaseAddr[48]; /* Function pointer of iROM's secure boot function */
unsigned char test_eFuse[MAX_EFUSE_DATA_LEN];
unsigned char reservedData[36];
} SecureBoot_CTX;
If i assume S3 still uses V1.1 security with 1024Bit RSA (BL1.bin is 8192Byte) the efuse key would be 128Bit, which results in 4 registers with 32Bit length.
Exported to a hex dat file this is 16Byte of Hex data.
Dump at 0x10100000 gives:
Code:
10100000: 0d19a391 2a0502af 1576987a 212121bc .......*z.v..!!!
We'll have to re-arrange the bytes for little endian order:
Code:
91a3190d af02052a 7a987615 bc212121
... use a hex-editor and put these into a file named: eFuseData.dat
Next i took codesigner_v21 and tried to validate stock BL1 files if they match.
codesigner_v21 -v1.1 <BL1.bin> <eFuseData.dat> -VERIFY
Unfortunately no succes yet... signature verification always failed.
This is a mistery, because the position of the key should be correct and i used valid bootloader files as well.
Anyway this had been only a proof of concept if we got the right tool and the right efuse values.
TBC
Cheers,
scholbert
@scholbert
Please, need collection of GT-I9305 Bootloader....
Something like this:
http://forum.xda-developers.com/galaxy-s3/general/guide-extract-bootloader-make-flashable-t2864264
http://forum.xda-developers.com/galaxy-s3/general/ref-galaxy-s3-stock-kernel-bootloaders-t2189063
For now I was only able to find
RESTORE_BOOTLOADER_I9305XXALI4.zip
http://forum.xda-developers.com/showpost.php?p=32760677&postcount=1
I need few more for stupid tests.
For now my test GT-I9300 PCB is able to start this sboot.bin from GT-I9305... with tweezer.
sboot.bin is copied successfully... but not start in "normal mode"...
Here I can see other method... sboot.bin is not copied to eMMC but fully executed from eMMC, with Boot menu:
http://forum.xda-developers.com/showpost.php?p=64664423&postcount=278
I will check if GT-I9305 has similar Bootloader and if it will executed on my GT-I9300 test PCBs.
Thanx in advance.
Best Regards
I found this:
I9305XXUFNL1-DBT.zip
Here is sboot.bin from GT-I9305 inside... I have attached.
Search for text String THOR... you can find:
Code:
- Thor is connected!
This could mean... I9305 is Tizen enebled... not only this...
Chance to play with U-Boot.
Tried on I9300 with no luck...
Volume + or Volume - do nothing... maybe Hardware Keys different...
I hope to find something working for my I9300...
Btw.
First time I saw THOR string also in Note 4 N910C:
http://forum.xda-developers.com/showpost.php?p=64663039&postcount=65
Best Regards
This thread is about hiding root. Feel free to discuss anything ranging from MagiskHide to suhide. See the suhide patching instructions below.
Introduction:
With the November security patches, Google back-ported a security feature that allows only a certain whitelist of filesystem sockets to be used.
This is the same feature that prevents suhide from working.
This particular commit is here:
https://android.googlesource.com/pl...8be33b0bedec211708c4525b9d3f3b4effb385c^!/#F0
If you are building CM or AOSP, all you need to do is revert this commit.
However, for binary builds a more direct patching approach is needed.
As I said earlier:
Fenny said:
The basis of my binary patches is to remove the function calls to
Code:
RuntimeAbort(JNIEnv* env, int line, const char* msg)
and remove a later reference to
Code:
gOpenFdTable
that was causing a crash.
Click to expand...
Click to collapse
ARM
Let me get into a bit more detail, and we can start with the error message that zygote spits out with an unpatched version of the file:
"Unable to construct file descriptor table"
We see that in the commit here:
Code:
+ // Close any logging related FDs before we start evaluating the list of
+ // file descriptors.
+ __android_log_close();
+
+ // If this is the first fork for this zygote, create the open FD table.
+ // If it isn't, we just need to check whether the list of open files has
+ // changed (and it shouldn't in the normal case).
+ if (gOpenFdTable == NULL) {
+ gOpenFdTable = FileDescriptorTable::Create();
+ if (gOpenFdTable == NULL) {
+ RuntimeAbort(env, __LINE__, "Unable to construct file descriptor table.");
+ }
+ } else if (!gOpenFdTable->Restat()) {
+ RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table.");
+ }
+
pid_t pid = fork();
When searching for references to the string in the disassembly of the file:
Code:
.text:000C8CC8 ADD R2, PC ; "Unable to construct file descriptor tab"...
.text:000C8CCA B loc_C8CDE
.text:000C8CCC BL sub_C845C
.text:000C8CD0 CBNZ R0, loc_C8CE2
.text:000C8CD2 LDR.W R2, =(aUnableToRestat - 0xC8CE0)
.text:000C8CD6 MOV R0, R4
.text:000C8CD8 MOV.W R1, #0x1D6
.text:000C8CDC ADD R2, PC ; "Unable to restat file descriptor table."
.text:000C8CDE BL sub_C873C
.text:000C8CE2 BLX fork
So, we're looking at the instruction "BL sub_C873C" as "RuntimeAbort" we know it's the right one because it is a conditional call just before the fork.
Which in hex is:
Code:
FF F7 2D FD
The simplest patch is to remove the function call entirely by replacing this with the arm equivalent of nop.
Code:
00 00 00 00
However, that breaks things because the file descriptor variable now contains a null where a reference should be.
Code:
.text:000C8D08 LDR.W R0, [R12]
.text:000C8D0C LDR.W R9, [R0,#8] ; <- Crash happens here.
.text:000C8D10 CMP.W R9, #0
.text:000C8D14 BEQ loc_C8D38
Hex:
Code:
DC F8 00 00 D0 F8 08 90 B9 F1 00 0F
So, since we always need to take the BEQ branch, we're going to replace the whole lot of functions with:
Code:
.text:000C8D08 MOVS R0, #0
.text:000C8D0A MOVS R0, #0
.text:000C8D0C MOVS R0, #0
.text:000C8D0E MOVS R0, #0
.text:000C8D10 MOVS R0, #0
.text:000C8D12 CMP R0, #0
Hex:
Code:
00 20 00 20 00 20 00 20 00 20 00 28
ARM64
The ARM64 patches are the same idea, but different opcodes:
In this example sub_881B8 calls our RuntimeAbort function, so first we nop out the call to that.
Replace:
Code:
.text:000000000014EF8C ADD X2, X27, #[email protected] ; "Socket name not whitelisted : %s (fd=%d"...
.text:000000000014EF90 MOV W4, W20
.text:000000000014EF94 MOV W0, #6
.text:000000000014EF98 MOV X19, #0
[B].text:000000000014EF9C BL sub_881B8[/B]
.text:000000000014EFA0 B loc_14ECA0
Hex:
Code:
87 E4 FC 97
Replace with:
Code:
.text:000000000014EF8C ADD X2, X27, #[email protected] ; "Socket name not whitelisted : %s (fd=%d"...
.text:000000000014EF90 MOV W4, W20
.text:000000000014EF94 MOV W0, #6
.text:000000000014EF98 MOV X19, #0
[B].text:000000000014EF9C NOP[/B]
.text:000000000014EFA0 B loc_14ECA0
Hex:
Code:
1F 20 03 D5
Next, we patch away the crash:
We want to take the CBZ X23, loc_151AC0 jump.
Replace:
Code:
.text:00000000001510CC ADRP X9, #[email protected]
.text:00000000001510D0 LDR X10, [X9,#[email protected]]
[B].text:00000000001510D4 LDR X23, [X10,#0x10][/B]
.text:00000000001510D8 CBZ X23, loc_151AC0
.text:00000000001510DC LDR X19, [X23,#0x18]
.text:00000000001510E0 CBZ X19, loc_1511F4
.text:00000000001510E4 BL sub_88468
.text:00000000001510E8 MOV X22, X0
.text:00000000001510EC ADRP X11, #[email protected] ; "/dev/null"
.text:00000000001510F0 ADD X24, X11, #[email protected] ; "/dev/null"
.text:00000000001510F4 B loc_151174
Hex:
Code:
57 09 40 F9
Replace with:
Code:
.text:00000000001510CC ADRP X9, #[email protected]
.text:00000000001510D0 LDR X10, [X9,#[email protected]]
[B].text:00000000001510D4 MOV X23, #0[/B]
.text:00000000001510D8 CBZ X23, loc_151AC0
.text:00000000001510DC LDR X19, [X23,#0x18]
.text:00000000001510E0 CBZ X19, loc_1511F4
.text:00000000001510E4 BL sub_88468
.text:00000000001510E8 MOV X22, X0
.text:00000000001510EC ADRP X11, #[email protected] ; "/dev/null"
.text:00000000001510F0 ADD X24, X11, #[email protected] ; "/dev/null"
.text:00000000001510F4 B loc_151174
Hex:
Code:
17 00 80 D2
Finally, nop out the second call to RuntimeAbort (ARM optimized these two calls into one, whereas arm64 split them into two subfunctions.)
Replace:
Code:
.text:0000000000151AAC MOV X0, X25
.text:0000000000151AB0 MOV W1, #0x1D3
.text:0000000000151AB4 ADD X2, X4, #[email protected] ; "Unable to construct file descriptor tab"...
[B].text:0000000000151AB8 BL sub_150264[/B]
.text:0000000000151ABC B loc_150F10
Hex:
Code:
EB F9 FF 97
Replace with:
Code:
.text:0000000000151AAC MOV X0, X25
.text:0000000000151AB0 MOV W1, #0x1D3
.text:0000000000151AB4 ADD X2, X4, #[email protected] ; "Unable to construct file descriptor tab"...
[B].text:0000000000151AB8 NOP[/B]
.text:0000000000151ABC B loc_150F10
Code:
1F 20 03 D5
TL;DR
I have this working on 7.1/7.1.1.
The gist:
Patching ART binaries required. System modification required. (can't bind mount modified ART or suhide breaks).
Known issues:
UI prompts to allow new or updated root apps do not display when suhide is enabled. (7.1.1+)
SuperSU 2.79 SR1 and above use incompatible selinux contexts with Suhide 0.55 and below.
JAYNO20 said:
I can confirm this works on the 5" Pixel device as well. This is NOT limited to just the XL.
Click to expand...
Click to collapse
Downloads:
Here are a couple patched versions:
libandroid_runtime_pixelxl_NDE63V.tar
libandroid_runtime_pixelxl_NMF26O.tar
libandroid_runtime_pixelxl_NMF26Q.tar
libandroid_runtime_pixelxl_NOF26V.tar (Reported working with NOF27B/C, N2G47E/J/K)
You WILL need to match your builds up.
Finally!
Cant wait for the write up!
ghostENVY said:
Finally!
Cant wait for the write up!
Click to expand...
Click to collapse
Well, since you can't wait... I will do a full write-up when I get home, until then, you can grab the modded Android runtime files from NDE63V: libandroid_runtime_pixelxl_NDE63V.tar
Basic process is: Replace modded files in system, fix permissions, flash suhide.
Will this work on NMF26Q?
Also, NMF26O?
Ker~Man said:
Will this work on NMF26Q?
Click to expand...
Click to collapse
JAYNO20 said:
Also, NMF26O?
Click to expand...
Click to collapse
ART libs look like they can be patched for both of those builds, but I haven't done them yet.
The old libs I posted probably won't set your phone on fire, but it is very likely you would have weird issues even if it doesn't just bootloop, which is what I would expect to happen.
JAYNO20 said:
Also, NMF26O?
Click to expand...
Click to collapse
So, after replacing the first of the four files, my phone froze immediately and now boots to an all black screen. Just fu**ing great...
Any ideas other than a full flash of stock???
Fenny said:
ART libs look like they can be patched for both of those builds, but I haven't done them yet.
The old libs I posted probably won't set your phone on fire, but it is very likely you would have weird issues even if it doesn't just bootloop, which is what I would expect to happen.
Click to expand...
Click to collapse
Any chance you'll get around to patching those as well?
JAYNO20 said:
Any chance you'll get around to patching those as well?
Click to expand...
Click to collapse
+1. Would be really nice...
Ker~Man said:
+1. Would be really nice...
Click to expand...
Click to collapse
I'd love to be able to use Android Pay again...
Ker~Man said:
So, after replacing the first of the four files, my phone froze immediately and now boots to an all black screen. Just fu**ing great...
Any ideas other than a full flash of stock???
Click to expand...
Click to collapse
Yeah, you're not going to be able to replace those files while you're booted into the normal system.
If you have a backup of the file restore it in recovery. If not, you'll probably need to flash a stock system partition.
It is likely that you did not get a chance to set permissions on the file when you replaced it. You can try going into recovery and try setting the correct owner and permissions on the file.
I'm so looking forward to this write up, thank you for your work!
Great job!
The anticipation is killing me
MyNarwhalBacon said:
The anticipation is killing me
Click to expand...
Click to collapse
Likewise!
Added some patched versions to the OP.
Write-up still pending. Working on an auto patcher for the files.
Fenny said:
Added some patched versions to the OP.
Write-up still pending. Working on an auto patcher for the files.
Click to expand...
Click to collapse
Nice work. Will the Q files work with the O update?
---------- Post added at 02:47 AM ---------- Previous post was at 02:34 AM ----------
Also, will this be ok to flash to the Pixel? (NOT XL)
Hi, great work. Is it doable for other brands (Sammy, Moto, Huawei...)? Any advice, paths to follow? Thx
Echoe™ team member / S7E
I tried on O update, bootloops.
You sir are the man. I'm excited to be able to root and still play Pokemon go
I wasn't sure where to post this. If this is better posted somewhere else, please tell me or move it.
LGUP comes in different variants. Dev, LAB, Store, 3rdParty.
Depending on the variant you're running, different features are exposed by your model.dll.
If you hack LGUP, you can unlock features!
Hacked LGUP:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Store LGUP:
I've tested the 'DUMP' function to see if the unlocked features are actually working, and yes, it works:
Unfortunatly, LG has implemented checks to prevent you from just modifying your LGUP.exe or LGUP_8994.dll to expose these features.
LG uses a temporary file to pass the features from the DLL to the application.
So it's just a matter of pausing LGUP at the right time, changing the file and voila.
I did it this way:
Load LGUP.exe in IDA (Interactive Disassembler),
Wait until it's done analyzing.
Set debugger to windbg. (F9)
Run the application (F9) one-time to fix the memory addresses..
You will get popups about exceptions, pass them to the application and continue running.
Exit LGUP.
Set break-point to loc_6989F. (if you can't find the location, search for string UI_Config.lgl, go to the code-xref where it's used and break there).
Run application.
When application stops at the breakpoint, open "C:\Program Files (x86)\LG Electronics\LGUP\model\8994\UI_Config.lgl" in a text-editor.
Find/replace "LAB" with "Store".
Save the file.
Continue running the application.
Tada, unlocked features!
holy crap, this is actually really helpful!
I've found another way to do this.
LGUP uses signature verification to prevent you from just hex-editing the files.
The LGUP.exe verifies the model.dll and the model.dll verifies the LGUP.exe.
I've patched this out of my model/8994/LGUP_8994.dll and modified LGUP.exe to look for strUser="DEV" instead of strUser="Store".
Now I can just start lgup.exe and get the 'Dev' functions.
I'm not sure how to distribute this.
I don't think I should just distribute modified versions of LGs software. This will make LG unhappy.
But I'm also not sure how to distribute binary patches in a way that's easy to use for others.
Here are my patches:
--- LGUP.exe (1.14.0.3)
Code:
@@ -2227,7 +2227,7 @@
00008b20: 0445 0400 0f84 4201 0000 8b96 5445 0400 .E....B.....TE..
00008b30: 8b3d fcf0 4300 6884 5144 0052 ffd7 8945 .=..C.h.QD.R...E
00008b40: dc85 c074 518b 8e40 0100 00e8 6047 0100 [email protected]`G..
-00008b50: 85c0 751b 8945 e068 f4c5 4400 8d45 e050 ..u..E.h..D..E.P
+00008b50: 85c0 eb1b 8945 e068 f4c5 4400 8d45 e050 .....E.h..D..E.P
00008b60: c786 3001 0000 0100 0000 e82d d602 00ff ..0........-....
00008b70: 55dc 83f8 ff75 1f68 f4c5 4400 8d4d d851 U....u.h..D..M.Q
00008b80: c786 3001 0000 0100 0000 c745 d800 0000 ..0........E....
@@ -7486,7 +7486,7 @@
0001d3d0: 55d8 53c7 45a4 3000 0000 895d a889 5dac U.S.E.0....]..].
0001d3e0: c745 b002 0000 0089 5db4 897d b889 7dc0 .E......]..}..}.
0001d3f0: 895d c489 5dc8 895d d089 55bc c745 cc00 .]..]..]..U..E..
-0001d400: 0100 00ff 1544 f443 003d 0901 0b80 7f69 .....D.C.=.....i
+0001d400: 0100 00ff 1544 f443 00b8 0000 0000 eb69 .....D.C.......i
0001d410: 7460 3d26 2009 8074 523d 0400 0b80 7444 t`=& ..tR=....tD
0001d420: 3d00 010b 8075 5dff 15d8 f043 003d 0001 =....u]....C.=..
0001d430: 0b80 741f 3d03 000b 8074 183d 0100 0b80 ..t.=....t.=....
@@ -18056,7 +18056,7 @@
00046870: 696f 6e00 504f 5349 5449 4f4e 0000 0000 ion.POSITION....
00046880: 6e58 506f 7300 0000 6e59 506f 7300 0000 nXPos...nYPos...
00046890: 6e57 6964 7468 0000 5355 5050 4f52 5400 nWidth..SUPPORT.
-000468a0: 7374 7255 7365 7200 5354 4f52 4500 0000 strUser.STORE...
+000468a0: 7374 7255 7365 7200 4445 5600 0000 0000 strUser.DEV.....
000468b0: 534f 4654 5741 5245 5f53 5441 5449 4300 SOFTWARE_STATIC.
000468c0: 534f 4654 5741 5245 5f43 5452 4c00 0000 SOFTWARE_CTRL...
000468d0: 4649 4c45 5f54 5950 455f 4558 0000 0000 FILE_TYPE_EX....
model/8994/LGUP_8994.dll:
Code:
@@ -6451,7 +6451,7 @@
00019320: 55d8 53c7 45a4 3000 0000 895d a889 5dac U.S.E.0....]..].
00019330: c745 b002 0000 0089 5db4 897d b889 7dc0 .E......]..}..}.
00019340: 895d c489 5dc8 895d d089 55bc c745 cc00 .]..]..]..U..E..
-00019350: 0100 00e8 3439 1a00 3d09 010b 807f 6774 ....49..=.....gt
+00019350: 0100 00e8 3439 1a00 b800 0000 00eb 6774 ....49........gt
00019360: 5e3d 2620 0980 7450 3d04 000b 8074 423d ^=& ..tP=....tB=
00019370: 0001 0b80 755b ff15 0c05 1e10 3d00 010b ....u[......=...
00019380: 8074 1e3d 0300 0b80 7417 3d01 000b 8074 .t.=....t.=....t
This looks very promising
So i can modify it to do all this my self or have u made a moded one we can download
TheMadScientist420 said:
This looks very promising
So i can modify it to do all this my self or have u made a moded one we can download
Click to expand...
Click to collapse
You should do this yourself for now.
I don't think I should distribute modded versions of other peoples copyrighted work.
Thanks for instructions one more time!
As h850 user i had to patch LGUP.exe as per your instructions and /model/Common/LGUP_Common.dll (just searched for "3d 09 01 0b 80 7f" and replaced with "b8 00 00 00 00 eb") .
:good:
RolF2 said:
Thanks for instructions one more time!
As h850 user i had to patch LGUP.exe as per your instructions and /model/Common/LGUP_Common.dll (just searched for "3d 09 01 0b 80 7f" and replaced with "b8 00 00 00 00 eb") .
:good:
Click to expand...
Click to collapse
That's great to hear!
Good idea to just search for those bytes and replace them.
If other people had succes with this I'm curious to hear about it.
Good tool to backup partitons before bootloader unlock and after, to see whats changed
i dont know i cant follow whats going on i got to the point of searching for b8 00 00 00 00 eb but cant edit it
RolF2 said:
Thanks for instructions one more time!
As h850 user i had to patch LGUP.exe as per your instructions and /model/Common/LGUP_Common.dll (just searched for "3d 09 01 0b 80 7f" and replaced with "b8 00 00 00 00 eb") .
:good:
Click to expand...
Click to collapse
so i found this line of hex but cant edit it
You can't save changes in hex editor? Then run hex editor as administrator, or copy files for editing to another disk and try again.
Just curious... Does anybody know what the "boarddownload" option does?? Does that backup the motherboards firmware or bios or something?? Sorry if the question sounds dumb. Im not a developer or anything.
OK, looks like too quiet here. We can dump all partitions from phone by "dump" function, also there's "partition dl" function - so looks like we can flash only one partition to phone... Problem is that program is crashing when i try to flash back dumped partition ... so how to convert dumped partition image to flashable img as simple renaming to img does'n work ?
RolF2 said:
OK, looks like too quiet here. We can dump all partitions from phone by "dump" function, also there's "partition dl" function - so looks like we can flash only one partition to phone... Problem is that program is crashing when i try to flash back dumped partition ... so how to convert dumped partition image to flashable img as simple renaming to img does'n work ?
Click to expand...
Click to collapse
it isn't a problem with the image, it's a problem with the patch... we should really look into how to fix this
@smitel
can you try "partition dl" function in IDA ?
Honestly Annoying said:
it isn't a problem with the image, it's a problem with the patch... we should really look into how to fix this
Click to expand...
Click to collapse
How do you know it's a problem with the patch?
RolF2 said:
@smitel
can you try "partition dl" function in IDA ?
Click to expand...
Click to collapse
What do you mean?
Figure out what it does/wants?
Look at your crash?
FWIW, I get "Error: General exception error in _initializeProcess()" when I try 'PARTITION DL'.
I'm guessing the 'DUMP' function produces a raw dump of the blockdevice, where 'PARTITION DL' requires a particular header (as in .TOT or .MBN) to define what gets flashed where.
FWIW, I find the following functions in my LGUP_8994.dll:
Code:
v5 = sub_1000B4F0(v4, (int)"REFURBISH", v3);
v8 = sub_1000B4F0(v7, (int)"UPGRADE", v6);
v11 = sub_1000B4F0(v10, (int)"CHIPERASE", v9);
v14 = sub_1000B4F0(v13, (int)"BOARDDOWNLOAD", v12);
if ( (v14 || v2 < 0xD || (LOBYTE(v14) = v2 != 13, v14)) && sub_1000C6A0(v1, "PROCESS_FAC_BOARDDOWNLOAD") )
if ( sub_1000C6A0(v1, "PROCESS_CS_WEBDOWNLOAD") )
if ( sub_1000C6A0(v1, "PROCESS_MBNBUILD") && sub_1000C6A0(v1, "TOT BUILD") )
if ( sub_1000C6A0(v1, "RECOVERY") )
if ( sub_1000C6A0(v1, "DOWNGRADE") )
if ( sub_1000C6A0(v1, "SCRIPT") && sub_1000C6A0(v1, "PROCESS_FAC_SCR") )
if ( sub_1000C6A0(v1, "PROCESS_FAC_UPGRADE") )
if ( sub_1000C6A0(v1, "PRL/ERI WRITE") && sub_1000C6A0(v1, "PRL UPDATE") )
if ( sub_1000C6A0(v1, "PRL/ERI READ") && sub_1000C6A0(v1, "PRL READ") )
if ( sub_1000C6A0(v1, "PHONESETTING") )
if ( sub_1000C6A0(v1, "PARTITION DL") )
if ( sub_1000C6A0(v1, "PB BACKUP") )
if ( sub_1000C6A0(v1, "PB RESTORE") )
if ( sub_1000C6A0(v1, "FOTA UPGRADE") )
if ( !sub_1000C6A0(v1, "DUMP") )
I try if I can follow the 'path' to understand what code gets called, but it's not very clear to me.
Every 'if' just results in a
Code:
*(_DWORD *)(v16 + 88) = 48;
}
else
{
*(_DWORD *)(v16 + 88) = 47;
}
}
else
{
*(_DWORD *)(v16 + 88) = 46;
But I haven't been able to follow what happens with it.
Here's a list of what functions are which 'ID'.
Code:
DUMP = 48 / 30h;
FOTA UPGRADE = 47 / 2Fh
PB RESTORE = 46 / 2Eh
PB BACKUP = 45 / 2Dh
PARTITION DL = 44 / 2Ch
PHONESETTING = 8 / 8h
PRL/ERI READ / PRL READ = 43 / 2Bh
PRL/ERI WRITE / PRL WRITE = 42 / 2Ah
PROCESS_FAC_UPGRADE = 0 / 0h
SCRIPT / PROCESS_FAC_SCR = 2 / 2h
DOWNGRADE = 41 / 29h
RECOVERY = 6 / 6h
PROCESS_MBNBUILD / TOT BUILD = 40 / 28h
PROCESS_CS_WEBDOWNLOAD = special
v15 = *(_DWORD *)(v16 + 1364);
if ( v15 == 3 )
*(_DWORD *)(v16 + 88) = 17;
else
*(_DWORD *)(v16 + 88) = 2 * (v15 == 5) + 16;
PROCESS_FAC_BOARDDOWNLOAD / BOARDDOWNLOAD = 7 / 7h
CHIPERASE = 32 / 20h
UPGRADE = 15 / Fh
REFURBISH = 9 / 9h
I was hoping to find a switch/case somewhere that would consume all these possibilities, but only find a partial one.
In sub_10081930() I see:
Code:
switch ( v1 )
{
case 40:
result = sub_10081570(this);
break;
case 45:
result = sub_1007E440(this);
break;
case 46:
result = sub_100807A0();
break;
case 2:
result = (*(int (**)(void))(*(_DWORD *)this + 60))();
break;
default:
result = sub_10083A70(this);
break;
}
And in this sub_1007E440() I see references to 'PB Backup', so this is one switch/case.
FWIW, when I rename my modemst1_COM7 to modemst1_COM7.tot I get error: "Error: TOT file is invalid[1]".
This message gets outputted by sub_1004CD20().
This might help with finding how/where stuff gets processed.
smitel said:
FWIW, when I rename my modemst1_COM7 to modemst1_COM7.tot I get error: "Error: TOT file is invalid[1]".
This message gets outputted by sub_1004CD20().
This might help with finding how/where stuff gets processed.
Click to expand...
Click to collapse
the .tot is a whole list of files i dont think renaming one partition to tot would work
it sucks i look at all ure guys partition and it a twrp heaven fro restore. i still cant get the patch to work.
i wonder if old lg firmware extractor or diagtool could repack these into a .tot format though it between the two of them they made all my hard brick restore images and carp for g2 g3 g4
i couldnt find a updated firehose bin for my g4 but still made a complete debrick image
---------- Post added at 10:22 AM ---------- Previous post was at 10:17 AM ----------
smitel said:
How do you know it's a problem with the patch?
What do you mean?
Figure out what it does/wants?
Look at your crash?
FWIW, I get "Error: General exception error in _initializeProcess()" when I try 'PARTITION DL'.
I'm guessing the 'DUMP' function produces a raw dump of the block device, where 'PARTITION DL' requires a particular header (as in .TOT or .MBN) to define what gets flashed where.
Click to expand...
Click to collapse
man if i can get this patch to work for me. im not so good in this area of Hex edit.
its been a long time. lol old nes roms. i thing with all these dumps I could get them repacked into a tot format that lgflashtool could use. in my case, i don't have a zva firmware released and i think i could put one together here
maybe you could explain to me better how to patch this i try searching can't find it half the time when i do even as adminstrator i cant edit the hex code.
Anyone have any luck running [the poc exploit](https://forum.xda-developers.com/ga...ompiled-executed-zero-day-exploitcve-t3978059) for CVE-2019-2215 on an Oreo LG V20? It's listed as one of the affected devices in the news reports. I'd love to get even a temp root.
For me (LS997) the poc stops with writev returning 0x1000 (it should return 0x2000 if the poc is working).
I have played around with the poc.c source code and noticed that if I change WAITQUEUE_OFFSET to 0x90, the device crashes and reboots. Since an untrusted app isn't supposed to be able to reboot a device, this suggests that there may be an exploitable thing around there somewhere.
Looking at the kernel source on the LG site (at least for the LS997), the LGV20 does have the bug in the kernel. However, the LGV20's kernel has a different layout of struct binder_thread than the version of the kernel the poc is designed for. And unfortunately it's not just a trivial fix, because the poc assumes the waitqueue field is 16-byte aligned, while on the LGV20 it's only 8-byte aligned (because there is one less field in the struct). There is probably a way around this, but I am not good at this sort of stuff: I don't really understand how the poc works. If anybody here does, maybe we can pool our minds and work together.
arpruss said:
Looking at the kernel source on the LG site (at least for the LS997), the LGV20 does have the bug in the kernel. However, the LGV20's kernel has a different layout of struct binder_thread than the version of the kernel the poc is designed for. And unfortunately it's not just a trivial fix, because the poc assumes the waitqueue field is 16-byte aligned, while on the LGV20 it's only 8-byte aligned (because there is one less field in the struct). There is probably a way around this, but I am not good at this sort of stuff: I don't really understand how the poc works. If anybody here does, maybe we can pool our minds and work together.
Click to expand...
Click to collapse
what is the waitqueue offset in the binder_thread struct in your kernel?
chompie1337 said:
what is the waitqueue offset in the binder_thread struct in your kernel?
Click to expand...
Click to collapse
0x98=152, assuming the kernel source I downloaded is correct and assuming I counted all the fields right. Here is my count (counting 64-bits at a time):
Code:
struct binder_thread {
struct binder_proc *proc; // 1
struct rb_node rb_node; // 4
struct list_head waiting_thread_node; // 6
int pid;
int looper; /* only modified by this thread */ // 7
bool looper_need_return; /* can be written by other thread */ // 8
struct binder_transaction *transaction_stack; // 9
struct list_head todo; // 11
struct binder_error return_error; // 15
struct binder_error reply_error; // 19
wait_queue_head_t wait; // spinlock_t + list_head
struct binder_stats stats;
atomic_t tmp_ref;
bool is_dead;
struct task_struct *task;
};
hmm. i see what you mean by alignment now.
this define
Code:
#define IOVEC_ARRAY_SZ (BINDER_THREAD_SZ / 16) //25
makes me believe that the size of iovec_array[ IOVEC_ARRAY_SZ] defined on line 75, has to equal size of struct binder_thread this is because somehow, the contents iovec_array overwrites the contents of a binder_thread structure. which means, that iovec_array[IOVEC_INDX_FOR_WQ] should contain the contents of binder_thread->wait.
wait_queue_head is defined as:
Code:
struct wait_queue_head {
spinlock_t lock;
struct list_head head;
};
meaning you have to make sure that the values in iovec_array[IOVEC_INDX_FOR_WQ] correspond correctly to the wait_queue_head but also line up so the writev works. there's definitely some trickery you could do to make this work. my first thought is you know that &iovec_arrary[9].len (offset 0x98) should point to values that make sense for a wait_queue_head struct. i'm working on understanding this better, though.
don't you guys think that 0xDEADBEEFs should go away before this so-called poc start working? any ideas on that one?
GoofMan69 said:
don't you guys think that 0xDEADBEEFs should go away before this so-called poc start working? any ideas on that one?
Click to expand...
Click to collapse
that's where the use after free bug should come in.
Code:
ioctl(binder_fd, BINDER_THREAD_EXIT, NULL);
when this is called, the binder_thread structure is freed in the kernel.
immediately after the parent process calls,
Code:
b = writev(pipefd[1], iovec_array, IOVEC_ARRAY_SZ);
in the kernel, memory is allocated to copy over iovec_array from userspace. this poc depends on the pointer from this allocation, to be the same as the recently freed binder_thread memory.
then, when the child process exits, the EPOLL cleanup will use the waitqueue in the binder_thread structure, that has been overwritten with the values in iovec_array. when EPOLL cleanup unlinks the waitqueue, 0xDEADBEEF will get overwritten by a pointer in kernelspace. this has to happen just before the writev call in the parent process starts to copy over the second buffer, which gets us a kernel space memory leak.
if writev is returning 0x1000 it means the timing is off, the wait queue offset is off, the kmalloc allocation in the writev function isn't the same as the freed binder_thread, or your kernel isn't vulnerable.
One simplifying issue is that with Kernel 3.18, we don't have KASLR, so we don't need to leak the kernel address. Hence the first part of the poc is unnecessary, assuming we can get the addresses.
Are there any rooted LGV20 variants using the 3.18 kernel? If so, it might help if someone with one of these were to post a copy of /proc/kallsyms
try
lg q710 kernel 3.18
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
chompie1337, thank you for such detailed description.
So, child must exit and epoll-cleanup code should be done to the time when parent's writev() starts to copy 2nd buffer (as you say, 0xdeadbeef will be replaced by that time). But there's a sleep(2) in the child. Do you think it is appropriate? Hardly it'll take writev 2s to copy first buffer, maybe 2ms or smth?
Also, why does child call epoll_ctl(EPOLL_CTL_DEL)? Isn't it a thing, that we should NOT do for the bug to come in?
From reading the poc, it looks like deleting the event from the epoll queue, after the binder thread has terminated, (somehow) causes the pointer wq->task_list->prev to have the value &(wq->task_list->next). If the kernel allocates its copy of the iovec array in the same place as the old binder_thread structure was, the wq->task_list->prev pointer will fall in an iov_base location in the array, and hence an iov_base will get overwritten. Moreover, the poc ensures this happens AFTER the kernel has checked that the iovec is one the user has permission to use for reading or writing. In the clobber function, then, the epoll event deletion makes the iov_base point to a position in the kernel heap--indeed, inside the kernel's pre-checked copy of the iovec array--which the poc leverages to write data to any location the kernel has access to (by first rewriting the next little bit of the pre-checked iovec array).
Unfortunately, with the 3.18 kernel, the event deletion causes a value to be written to an iov_len location in the iovec array, which allows one to change the amount of data being written but not the location being written to. This is good enough for crashing the device and probably for leaking a lot of data, but I have not been able to figure out how to use it for rooting.
If the kernel could be manipulated to allocate its copy of the iovec array 8-bytes further down in the heap, that would solve the problem, but I don't know if it can be done: I don't think the kmalloc-512 allocator will do that. But I could be wrong. Otherwise, I think one needs some other technique than the readv/writev trick used in the poc.
I am, unfortunately, quite new to this kind of thing. An experienced kernel hacker can probably see in an instant what to do.
I'm not sure the PoC crash is entirely because of the kernel version. My device (not the V20, just here to cooperate to develop the exploit) has kernel version 4.4 but it crashes at the first EPOLL_CTL_DEL. Where does the V20 crash when you change the WAITQUEUE_OFFSET?
Oh, I see... So writev would block after writing first dummy_page_4g_aligned of length 0x1000, because pipe's queue is full (pipe size is also 0x1000). So there isn't actually any timing tweak required, right?
Btw, i've managed to get some memory from kernel (from my device, not the V20) and non-null curent ptr, but kernel_read fails, even when reading 4 bytes from cur_ptr without any offset
Can anyone comment on line 119:
current_ptr = *(unsigned long *)(page_buffer + 0xe8);
What is 0xE8? Where does it come from?
Another strange thing: if i run poc with wd offset like for ex. 0xb0 right after reboot - i get another reboot right away, repeatability 100%. but if i run at first with offset like 0xc0 - of course i get writev 0x1000 and poc exits, but if i rerun poc with 0xb0 right after that - it will not cause reboot, but correct leak of mem happens
GoofMan69 said:
Oh, I see... So writev would block after writing first dummy_page_4g_aligned of length 0x1000, because pipe's queue is full (pipe size is also 0x1000). So there isn't actually any timing tweak required, right?
Click to expand...
Click to collapse
The sleep(2) is needed to make sure the THREAD_EXIT, which frees the binder_thread object, as well as the subsequent allocation of the iovec buffer in kernel memory take effect before the EPOLL_CTL_DEL. The pipe blocking happens only after the the EPOLL_CTL_DEL.
Can anyone comment on line 119:
current_ptr = *(unsigned long *)(page_buffer + 0xe8);
What is 0xE8? Where does it come from?
Click to expand...
Click to collapse
I'm guessing that 0xe8 comes from the author's looking at a hexdump of the page to find where there is a pointer to kernel stuff to help figure out where the address limit is held in memory, so it can be clobbered.
GoofMan69 said:
Oh, I see... So writev would block after writing first dummy_page_4g_aligned of length 0x1000, because pipe's queue is full (pipe size is also 0x1000). So there isn't actually any timing tweak required, right?
Btw, i've managed to get some memory from kernel (from my device, not the V20) and non-null curent ptr, but kernel_read fails, even when reading 4 bytes from cur_ptr without any offset
Can anyone comment on line 119:
current_ptr = *(unsigned long *)(page_buffer + 0xe8);
What is 0xE8? Where does it come from?
Another strange thing: if i run poc with wd offset like for ex. 0xb0 right after reboot - i get another reboot right away, repeatability 100%. but if i run at first with offset like 0xc0 - of course i get writev 0x1000 and poc exits, but if i rerun poc with 0xb0 right after that - it will not cause reboot, but correct leak of mem happens
Click to expand...
Click to collapse
page_buffer + 0xe8 should point to the current thread's thread_info structure, where the addr_limit is held
---------- Post added at 08:35 AM ---------- Previous post was at 08:19 AM ----------
arpruss said:
From reading the poc, it looks like deleting the event from the epoll queue, after the binder thread has terminated, (somehow) causes the pointer wq->task_list->prev to have the value &(wq->task_list->next).
Click to expand...
Click to collapse
yes, you are correct. i believe it is because remove_wait_queue is called for the wait_queue_head found in the binder_thread structure which eventually results in a call to __list_del where this happens:
http://androidxref.com/kernel_3.18/xref/include/linux/list.h#87
I can now leak data on my LGV20 with the 3.18 kernel using this modified poc: https://github.com/arpruss/cve2019-2215-3.18
The key is to realize that the following happens during the after-free cleanup at least on my 3.18.71 kernel:
1. The spinlock appears receive the value 0x10001
2. The prev and next pointers in the queue head point to the queue head.
If everything works, you will have a bunch of hex data, which starts with two 8-byte pointers with equal values.
This may or may not get us closer to actually elevating privileges, but I thought I'd share it to help others.
Code:
1|elsa:/data/local/tmp $ uname -a
Linux localhost 3.18.71-perf+ #1 SMP PREEMPT Tue Jul 17 14:44:34 KST 2018 aarch64
elsa:/data/local/tmp $ ./poc98
Starting POC
PARENT: Calling WRITEV
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: initial page
CHILD: dummy data
CHILD: leak data
writev() returns 0x12001
CHILD: Finished write to FIFO.
PARENT: Done with leaking
00000000 a0 f8 c4 f3 c0 ff ff ff a0 f8 c4 f3 c0 ff ff ff |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
arpruss said:
I can now leak data on my LGV20 with the 3.18 kernel using this modified poc: https://github.com/arpruss/cve2019-2215-3.18
The key is to realize that the following happens during the after-free cleanup at least on my 3.18.71 kernel:
1. The spinlock appears receive the value 0x10001
2. The prev and next pointers in the queue head point to the queue head.
If everything works, you will have a bunch of hex data, which starts with two 8-byte pointers with equal values.
This may or may not get us closer to actually elevating privileges, but I thought I'd share it to help others.
Code:
1|elsa:/data/local/tmp $ uname -a
Linux localhost 3.18.71-perf+ #1 SMP PREEMPT Tue Jul 17 14:44:34 KST 2018 aarch64
elsa:/data/local/tmp $ ./poc98
Starting POC
PARENT: Calling WRITEV
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: initial page
CHILD: dummy data
CHILD: leak data
writev() returns 0x12001
CHILD: Finished write to FIFO.
PARENT: Done with leaking
00000000 a0 f8 c4 f3 c0 ff ff ff a0 f8 c4 f3 c0 ff ff ff |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Click to expand...
Click to collapse
Nice work. Now without the spinlock issue crashing, the kernel write is failing. This is because the recvmsg implementation for the 3.18 kernel checks each address right before it's copied over to the buffer. In the writev/readv the access check for addresses are all done at once at the beginning of the call, so that's why the leaking works. Working now on trying to use readv instead of recvmsg
chompie1337 said:
Nice work. Now without the spinlock issue crashing, the kernel write is failing. This is because the recvmsg implementation for the 3.18 kernel checks each address right before it's copied over to the buffer. In the writev/readv the access check for addresses are all done at once at the beginning of the call, so that's why the leaking works. Working now on trying to use readv instead of recvmsg
Click to expand...
Click to collapse
It was tricky to get it working, but I can now write to an arbitrary kernel address using: https://github.com/arpruss/cve2019-2215-3.18/blob/master/poc98-overwrite-pipe.c
Unfortunately, one more ingredient is needed: I need the address of the thread_info structure in order to modify addr_limit. On 4.4+, this is easy, as it's part of the task_struct, which the leaked current_ptr points to. On 3.18, thread_info is at the beginning of the kernel stack. So what we need to do is to leak the kernel stack location. If you know how to do that -- e.g., extracting it in some way from the big kernel heap leak -- let me know.
Or one use some other method. For instance, one can heap spray with a bunch of struct file objects, use the big kernel heap leak to find one of the sprayed objects (e.g., one can seek to a unique random location in a sparse file, and search for that offset in the leaked kernel heap), and modify its ops pointer to point to a doctored list of ops that calls a user function. I think this should work, unless we're unlucky and the binder_thread object is not anywhere near one of the sprayed file objects.
Or else if someone has the exact same kernel on a rootable device, they could send me the output of cat /proc/kallsyms, and one could modify some syscall to call a user function.
Now that I have a big kernel heap memory leak plus arbitrary address writing it's just a matter of time before we have a full exploit, I expect.
arpruss said:
It was tricky to get it working, but I can now write to an arbitrary kernel address using: https://github.com/arpruss/cve2019-2215-3.18/blob/master/poc98-overwrite-pipe.c
Unfortunately, one more ingredient is needed: I need the address of the thread_info structure in order to modify addr_limit. On 4.4+, this is easy, as it's part of the task_struct, which the leaked current_ptr points to. On 3.18, thread_info is at the beginning of the kernel stack. So what we need to do is to leak the kernel stack location. If you know how to do that -- e.g., extracting it in some way from the big kernel heap leak -- let me know.
Or one use some other method. For instance, one can heap spray with a bunch of struct file objects, use the big kernel heap leak to find one of the sprayed objects (e.g., one can seek to a unique random location in a sparse file, and search for that offset in the leaked kernel heap), and modify its ops pointer to point to a doctored list of ops that calls a user function. I think this should work, unless we're unlucky and the binder_thread object is not anywhere near one of the sprayed file objects.
Or else if someone has the exact same kernel on a rootable device, they could send me the output of cat /proc/kallsyms, and one could modify some syscall to call a user function.
Now that I have a big kernel heap memory leak plus arbitrary address writing it's just a matter of time before we have a full exploit, I expect.
Click to expand...
Click to collapse
Amazing work! Going to try it out now. How do you know that current_ptr points to task_struct? On my Pixel (3.18 kernel) current_ptr points to thread_info. Wondering why that's different?
edit: nvm, i see now. it's in an offset of the binder_thread structure.
arpruss said:
It was tricky to get it working, but I can now write to an arbitrary kernel address using: https://github.com/arpruss/cve2019-2215-3.18/blob/master/poc98-overwrite-pipe.c
Unfortunately, one more ingredient is needed: I need the address of the thread_info structure in order to modify addr_limit. On 4.4+, this is easy, as it's part of the task_struct, which the leaked current_ptr points to. On 3.18, thread_info is at the beginning of the kernel stack. So what we need to do is to leak the kernel stack location. If you know how to do that -- e.g., extracting it in some way from the big kernel heap leak -- let me know.
Or one use some other method. For instance, one can heap spray with a bunch of struct file objects, use the big kernel heap leak to find one of the sprayed objects (e.g., one can seek to a unique random location in a sparse file, and search for that offset in the leaked kernel heap), and modify its ops pointer to point to a doctored list of ops that calls a user function. I think this should work, unless we're unlucky and the binder_thread object is not anywhere near one of the sprayed file objects.
Or else if someone has the exact same kernel on a rootable device, they could send me the output of cat /proc/kallsyms, and one could modify some syscall to call a user function.
Now that I have a big kernel heap memory leak plus arbitrary address writing it's just a matter of time before we have a full exploit, I expect.
Click to expand...
Click to collapse
Isn't thread_info pointed by the stack field of task_struct?