Related
I'm currently doing a little reverse engineering of Coredll so that I can understand how a few functions work. Occasionally I run across a function call to an address similar to F000BDD8. Is this a function call into the kernel or does it correspond to an address in the dll? If someone could point me to the correct reference, I'd appreciate it.
This is how it is layed out:
LDR r0, &0000b650
MOV lr, pc
MOV pc, r0
And at address 0000b650 the value is F000BDD8.
Thanks!
it is something like a "syscall" command on WinCE. The "FIRST_METHOD" value (0xF0010000) is subtracted form the given address, then value is divided by 2 (in your case we get -8468 or 0xff..ffdeec). If the value is negative it is "API call to an implicit handle. In this case, bits 30-16 of the method index indicate which entry in the system handle table." (probably its a typo in comment, bits 8-22 are used instead of 30-16). Lower bits are offset in SystemAPISets[] table for the function address.
For more information look into PrefetchAbort function in "PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARM\armtrap.s" file, and ObjectCall function in "PRIVATE\WINCEOS\COREOS\NK\KERNEL\objdisp.c"
You should get PlatformBuilder and look into Wince 4.20 partial source code that is coming with it. It does not have much information on indexes inside SystemAPISets table for any table except for SystemAPISets[SH_WIN32] (SH_WIN32 == 0).
see this page for a list of systemcalls.
and this page for a description of how systemcalls work.
to convert a trap address ( like 0xF000BDD8 ) back to the syscall nrs:
Code:
$a= (0xf0010000-$addr)/4; # = 0x108a
$api=$a>>8; # 0x10 = SH_GDI
$call=$a&0xff; # 0x8a = ExtCreateRegion
( call defined in public/common/oak/inc/mwingdi.h )
hmm. not sure which is correct though, my wince-systemcalls page lists a different call signature than the headerfile. they should match.
Thank you for the information. I actually have the sample source that comes with the Platform Builder demo. In this case, the call I was investigating was the GetSysColorBrush API.
That brings me to another point. In several of the APIs a check is made to a value (KData->lpvTls[-20], I believe) to see if the 0-bit is 1. The only thing I can determine is whether or not this is checking for the ready state of the API. Whatever the case, it seems that this bit determines whether the function I mentioned earlier is called or whether a function address is loaded from RAM. It's really weird.
The main reason I'm doing this is so that I can access the system's brush cache for the system colors. I've noticed that if I intercept calls to GetSysColor and GetSysColorBrush, it only works for applications that have not called them yet. So, if I override the color for COLOR_BTNFACE, menubars for newly launched applications are colored correctly, but buttons (which belong to GWES) do not use the appropriate color. It's weird because my code has been injected into GWES.Exe.
I guess that brings me to my ultimate question of whether or not someone can point me to the location in RAM where the system brush cache is stored.
Thanks!
is the '-20' in bytes ?
in PUBLIC/COMMON/OAK/INC/pkfuncs.h
#define PRETLS_THRDINFO -5
#define UTLS_INKMODE 0x00000001 // bit 1 set if in kmode
#define IsThrdInKMode() (UTlsPtr()[PRETLS_THRDINFO] & UTLS_INKMODE)
this must be the bit that is set when calling 'SetKmode();'
Yeah, the -20 is in bytes. Here's the disassembly of what I was looking at:
00B5EC E59F6068 LDR r6, &0000B65C
00B5F0 E59F5060 LDR r5, &0000B658
00B5F4 E5960000 LDR r0, [r6, #0]
00B5F8 E5101014 LDR r1, [r0, #-20]
00B5FC E3110001 TST r1, #1
00B600 15950000 LDRNE r0, [r5, #0]
...
00B650 F000BF08 ANDNV r11, r0, r8, LSL #30
00B654 01FC6758 MVNEQS r6, r8, ASR r7
00B658 01FC6760 MVNEQS r6, r0, ROR #14
00B65C FFFFC800 SWINV &FFC800 <-- Points to KDataStruct
What you said makes sense, yet it seems kind of strange that this API would be looking at an offest of -20.
so what you are seeing, is a call to 'IsThrdInKMode()' .
there is a space of thread local storage used by the kernel, just before the publicly accessible thread local storage. - look for SIZE_PRETLS, and PRETLS_RESERVED in the wince source.
this function ( well implemented as a macro actually ) is not a very strange function to call from a system call.
btw, you should have a look at IDA from datarescue. it will give you a much more readable disassembly. the stuff in your example from 00b650-b65c will be recognised as a constant pool, and the references to it, like at 00b5ec will be disassembled as 'LDR r6, =0xffffc800'
The only problem I have with IDA is that I can't afford it and their demo doesn't handle ARM processors. The generated output was done with a fairly simple program and has forced me to learn quite a bit about the underlying code in the OS. I've had to go back and forth between the disassembly and the shared source, but I've managed so far (with this exception).
I do have one other question while I have your attention. I've managed to inject a dll into all of the running processes and I've successfully managed to intercept several APIs by patching an application's IAT (and all attached modules, too) in an attempt to provide a better color handler for the system. It appears, however, that some programs, like Gwes.exe, don't use call my functions, but instead call the functions built into Coredll. For example, the GetSysColorBrush I mentioned earlier. This is what prompted me to begin reverse engineering Coredll in the first place. Do you know if the addresses are being stored somewhere? If so, that would explain why even though I've patched the IAT that the original function is still being called.
contact me in PM, I can help with IDA 4.51 full
gwes.exe is the program implementing the API, so quite likely it either calls it's api's directly, or calls the systemcalls directly.
and maybe someprograms are linked to a statically linked version of coredll?
a while back I experimented with trapping systemcalls, by modifying the method table in an API. ( see hookapi.cpp )
I do remember that my device became very unstable. so I guess that it somewhat worked, but haven't figured out what exactly I did wrong yet.
btw, I would be quite interested to see your code to trap calls via the IAT.
When you have a look to romimage.exe source code in platform builder you will notice that there is a special handling for coredll.dll.
All programs included in the MODULES section will directly resolve calls to coredll.dll. Only if you build a new XIP section a warning will appear "missing coredll.dll ... will late bind".
This means that a hook to coredll.dll will not be visible for in ROM programs since they will call the system functions directly (without the trap).
John
itsme said:
btw, I would be quite interested to see your code to trap calls via the IAT.
Click to expand...
Click to collapse
Unfortunately, I'm not at the computer where I have the code, so I'll have to upload it to you tomorrow. However, it involves extracting the IAT from the PPROCESS structure of a given program, then enumerating through the entries until I find the API I'm looking for. It's actually pretty straight forward. Give me your email address and I'll send it to you as soon as I can.
JohnSmith said:
When you have a look to romimage.exe source code in platform builder you will notice that there is a special handling for coredll.dll.
All programs included in the MODULES section will directly resolve calls to coredll.dll. Only if you build a new XIP section a warning will appear "missing coredll.dll ... will late bind".
This means that a hook to coredll.dll will not be visible for in ROM programs since they will call the system functions directly (without the trap).
Click to expand...
Click to collapse
I don't have the full source code, only what's available in the shared source, so I'm not sure what modules would be affected. However, I'm really only interested in a few of the Gwes APIs. I know it's possible at least at some point to hook into those as I've seen it done, though the individual who did it is under an NDA and can't tell me how he did it.
Itsme's process looks to be about the best so far, assuming I can get it to work. The only thing is that I need to find a way to translate the physical address to a virtual adress (and vice-versa) for MIPS, SH3 and the emulator, not just the ARM/XScale processors. If I could do that, then I might be able to get things to work.
Thanks for all of your help so far. I appreciate the time you have spent in explaining a few things to me.
[email protected]
for translating physical to virtual you would need to find the translation tables for each process, which I assume must exist somewhere, but have not found them yet. - my guess is it may be the 'pPTBL' entry from the process struct, but have not verified this yet.
( you know that virtual addresses can not uniquely be translated back to physical without knowing what process they are for? for instance the virtual address 0x11000 is visable in each process, and mapped to a different physical address each time. )
Fortunately, I've written an OS before, so I know what you mean about address mapping. If the pTBL does contain the page mappings, that would make sense. I found it easier in my OS to keep the TLB entries with the process they belonged to. That way the OS wouldn't have to search through its memory chain looking for the process's mappings.
Also, if the pTBL does contain the TLB entries, then it should be relatively easy to decode the addresses. After reading your code, itsme, I determined that the CINFO structure holds a pServer field which points to the process which contains the APIs. So, for example, the GDI and USER API sets are being held in Gwes.exe (at least, according to the pServer field). The ppfnMethods field is a VA referring to the pServer. If pServer is NULL, then the ppfnMethods field seems to be a PA. So, what I could do is check for pServer. If it is NULL, I could use the current process's pTBL structure to map the PA to a VA. If the pServer field is non-NULL, then I could try the pServer's pTBL field to do the mapping and then do the replacement that way.
If this works, I owe you big!
here is another experimental program, that investigates all the handles present in the system.
I used it to generate this overview of handles.
Progress So Far
I just thought I'd post an update on my progress so far. It appears that I can overwrite the API table pretty easily. Instead of taking a physical address, the table takes a pointer to a function in virtual memory. You just need to map it to slot 0 using MapPtrToProcess.
I've come across two issues in doing this. The first thing is that I can't call the original function address. For example, I store the original address contained in ppfMethods[x] and then attempt to typecast it to the proper function type, passing the incoming variables.
The other issue is that it appears that the API table is NOT refreshed upon a soft-reset. Fortunately, I was playing around with it on the emulator. Had I not, I would have been forced to hard-reset my device.
Does anyone have ideas on either of these issues?
Thanks again for your help so far!
a thing that just occurred to me, is that if you duplicate the apiset struct, the memory pointed to by ppfnMethods should be readable from the process specified in pServer.
so you should allocate the memory in the address space of pServer.
or set pServer to yourself, and add some hook code which does not modify the stack, so you can just pass most calls directly to the original server.
to call the original function address, you have to somehow switch process context, and then call it.
Well, in the case that I tested, I replaced the QueryAPISetID API which exists in Wn32 and therefore has no pServer. It appears that if there is no pServer, then there is no context switch needed. I've been able to verify that the API will execute my code and the generated assembly does not modify the stack in any way.
This one is really weird. Thanks for the suggestions.
chmckay said:
itsme said:
btw, I would be quite interested to see your code to trap calls via the IAT.
Click to expand...
Click to collapse
Unfortunately, I'm not at the computer where I have the code, so I'll have to upload it to you tomorrow. However, it involves extracting the IAT from the PPROCESS structure of a given program, then enumerating through the entries until I find the API I'm looking for. It's actually pretty straight forward. Give me your email address and I'll send it to you as soon as I can.
Click to expand...
Click to collapse
Hi,
Just wondring if you could post/PM/email me the code that lets you replace the API call. This is for the purpose of hooking a different DLL to do my own thing, or see here:
http://forum.xda-developers.com/viewtopic.php?p=131857#131857
I just sent you a PM with the information you requested.
I was wondering if anyone here could help me out.
I have a need to intercept a couple of GDI apis. At this point, I can successfully inject a library into GWES and hook the apis using the api set data structure contained in the kernel's memory (i.e. KDataStruct->aInfo[KINX_APISETS]). However, this doesn't work when Gwes calls the api internally.
So, I came up with a method that allows me to "hook" the api, similar to the way Detours works. What I did was allocate 8 bytes of virtual memory and copy the first instruction of the api to the first 4 bytes of the memory block. Then, I created an ARM branch instruction to jump from the second 4 bytes of the buffer to the second instruction in the original api, kind of creating a trampoline function. Then, I created one more branch that jumped to my new function and overwrote the first instruction of the original function.
Basically, this is what ends up happening:
The api is called
The function branches (unconditionally) to my function
My function calls the trampoline function
The trampoline executes the first command of the original function (the one that was overwritten) and branches unconditionally to the original function
The original function does its thing and returns to my function
My function handles whatever it needs and returns to the caller
Now, here's the problem. On my handheld, it works flawlessly. However, this code did NOT work on several other devices, causing freezes and hard-resets. I was wondering if anyone knows what I can do to get this fixed.
Here's how I calculate a branch:
branch = (((dest-source-8)>>2)&0xffffff)|0xea000000;
I've verified that all of the values come out correctly for the ARM specifications.
If anyone can help, I'd really appreciate it.
Thanks!
3 ideas. First is dumb. Maybe these devices keep GDI code you are trying to patch in ROM?
The second idea. Maybe the GDI code is mapped to every process address space without any modifications, and when your hook is called, some of the processes does not have your injected code in them and jump goes to unexistent address -> crash. You may try to use a jump command that uses full 32 bits of adress and a MapPtrToProcess() function to get your address that is visible in every proccess. In this case you should patch 8 bytes of hooked command.
The third idea. Are you sure that the patched bytes does not contain instructions that use PC-relative offsets? In this case you'll have to emulate them manually.
Well, all GDI/USER functions exist in Gwes.Exe. When you call something like BeginPaint, coredll transfers control to Gwes, Gwes makes the function call and control returns to the application. So placing a hook in Gwes is the best location.
On the ARM/Xscale platform, all branches are relative to the PC. My example in my first post shows how the branch offset is calculated. Each branch must be within 32MB (24-bits). The first instruction of the function I'm hooking, according to IDA, is an STFMD.
So, I thought that my original problem was that the jumps were more than 32MB away. However, I've confirmed that this is not the case in any of the crashes, which is why I'm confused.
I believe I wrote everything to ARM specifications, but I guess not. If it will help, I xan post some of code for a reference.
instead of a jump, maybe use
Code:
04 F0 1F E5 LDR PC, [PC-4]
xx xx xx xx DCD jumptarget
hi,
I have a program and it has lots of settings saved in memory, when I exis the program I need to save settings in a config file.
My program has CString(s), CArray(s) and other basic int and DWORD varibles, so how can I save such complex settings?
Mohammad
as xml maybe
If you're using MFC you could always attach a CArchive to a file and serialize
Perhaps you need to either create a log file - for debugging purposes or save your settings to the registry. If its the former then, check this one http://www.codeproject.com/ce/GenericLogFunctionality.asp it should be helpful. If its the latter, then you just search codeproject and you'll find lot of tutorials on the registry. Also, you can use CEDB which is a flat table data base that can store many data type structures including files and images, use it if you need to.
It may seem like you're lost now, but you can take an overview about the cons and pros of each technique so as to choose the best one for you.
For my config file I use plain english bounded by my own tags. I use a character sequence as a seperator for lists. I convert numerical values into text that can be human readable. There are some benefits to being able to read and edit it manually if the need arizes. I also made a class purely for writing and reading from my config file. Now when I to use a config file I can just drop that class into my project.
XML sounds good and similar but it would require a greater knowledge of xml.
Registry is easier and faster to do/execute but for data that can potentially grow too much it is probably best to keep it out of registry.
Is CArray serializable? do we just simply use CArray::Serialize and it will dump all included objects into a file?
thanks
http://msdn2.microsoft.com/en-gb/default.aspx
this site may be helpfull while you wait for somebody to answer your question
If you can it would be easier to use CObArray and ensure that the array members are subclassed from CObject with the DECLARE_SERIAL / IMPLEMENT_SERIAL macros. You could also add a new << operator to the CArchive class and write the serialization routine but that would kinda defeat the object I guess.
I solved the issue using serialization, for CArray structures I used the following method:
File<<MyArray.GetSize();//store how many objects
for(all my objects in the CArray)
serialize them one by one
I did the same when loading and it works flawlessly.
Thanks all for your help
I have been trying to get a better understanding of CRC calculations. There is a lot of table based code that can be used available freely on the net but I want to implement my own basic technique first to get a fuller understanding. I have made a class to do the calculations and manually calculated an example to verify the code and they both agree. The problem is that based on this http://www.createwindow.com/programming/crc32/crcverify.htm my answer is wrong. If anyone could look over the attached txt file I would be great full. I can't post it here because the formatting would be lost and it would be impossible to read (very long division). The text I crc is resume (only those chars). The polynomial I use is the standard one used in zip 0x04C11DB7 when computing or 0x104C11DB7 when doing manually (the msb always cancels out).
It could just be that a table driven implementation generates a different crc, but I doubt it.
(log on to see attachment)
The program updated. free to use ...
Hi all, I write a simple program for Telecom. Engineeger:
1) It can show CellID, Rxlev & LAC
2) base on the database (txt file), show cell site info.
3) GPS function
4) Open log file to record
The Log file format in :
Latidute,Longitude,CurrentTime,CellID,Rxlev
And you need to copy the files 2G.txt,3G.txt & site.txt to the root directory.
the text file at the main program directory ( eg. program file\fieldtestv1.2\).
Note:
Only test at my HTC P3600i phone, not sure for others ...
And sorry for my poor english ..
New Version ,It's surprised,But My PPC(model:O2 atom Life) Cell Id is Error。
Picture :
I have this error on my "Tornado" smartphone (WM 6.1).Why ?
By default, the program will read the files "2G.txt", "3G.txt", "site.txt" & "SiteNo.txt" when startup. so if you missing one of file , it will show the error message. you should create the 4 txt file to the root directory.
If you are a telecom engineer, you may entry the field data to each txt file or just create a empty file, it should be work !!!
that's a brilliant program.
btw what's the file format for the SiteNo.txt and is there a way to change the frequency of the log file to every minute or 30 seconds.
It would be great if you could do the site info match using the cellid ( CI ) and LAC. due to certain telco would recycle the cellid due to the 65536 limit.
Few more suggestion for the Log file.
1. Log file can be saved to storage card
2. BCCH info from the cells not from the txt file included in the log file
3. Logging frequency i.e 10 secs , 30 secs , 1 minute
4. LAC included in the log file
It is actually 8 to 10 db more when compared with an actual test tools.
bravo it's a good program.
Almost works, it crashes when i hit start or update, on my 8525 with ATT Wm6, files attached.
How do you read CELL ID ?
It is in the registry? where ?
could you show some code how to get cellid? which serial port to be opened?
On My HTC9000 PPC, I couldn't open COM2, No Com ports could be send AT
Cmd successfully
Some source code here ...
public static CELLINFO GetCellTowerInfo()
{
IntPtr res = IntPtr.Zero;
res = RIL_GetCellTowerInfo(hRil);
if ((System.Int32)res > 0)
{
rilCmd.CmdId = (System.Int32)res;
rilCmd.CmdType = RIL_CMD_TYPE.CELLTOWERINFO;
......................
.......................
if (!RIL.isInitialized)
RIL.Initialize();
RIL.CELLINFO CID = RIL.GetCellTowerInfo();
I have just started using this program as I am a telecommunications engineer.
I have emailed Frank for assistance and he has been most helpful.
The TXT files must be placed in the / directory - ie the "My Device" directory.
I have also noticed that if I use 2G or 3G mode on my phone, the program only looks in the 2G.txt file.
Try on my Hermes, on 3G band it shows only Cell ID, other failed, on 2G it shows MCC-MNC, Cell ID and LAC, but not signal level neither SC? Just reporting
Unsure why this is not receiving signal level, but the program does not yet have the functionality to extract BCCH/PSC.
All this program tries to match is the CellID - you need to have the BCCH/PSC in 2G.txt or 3G.txt
I am currently speaking with the developer to see if he wants some assistance to work on this program (i can test) - I am using a Touch Diamond
Thanks!
Dear Frank8080,
Thank you for your cellid sample program. I download and try it. This program run into my cht9100 very fine. I need one program to get cellid on wm6. Can you email your source code to me ? Thank you very much!
Does it work on wm2003 for my 818?
It does NOT work on O2 Atom, windows mobile 6 ...
hmmm... It crashed in my atom wm5.0.
Thanks for the bug reporting:
1) For the program can't read 2G or 3G txt, due to the program read the txt file base on the MNC(Network Code), so it seens that I need to add a setup page to fix the problem.
2) For can't decode the signal level (erwinpiero), I have tested on Dopod 838 Pro, it works ok. But I don't know why it's not work on your 838Pro.
3)For BCCH/PSC decoding, I still try ....
I am a mobile engineer in HongKong and the program just developed for my team use to perform the field measurement of the daily operation, so the most of function just base on the needs of my job. So if any other information you need, you may email to me, I will try to add the extra function to the program.
Hi frank, Top program, well done!! it's running on my TyTN II fine.
Could you post up some examples of how the 4 txt files should be built and a "few" examples of the info they should contain.
Also I see you're using RIL ... does your program update the CellID etc whilst the phone is "In Call". I have used CellTrack before and once "in call" the phone never updates apart from the RX level.
Thanks!!
Phil
Hi,
I haven't tried this sw, but I will do it soon (as soon as I have a PDA).
Just wondering if is possible to select what variables should be on the log (e.g.: active set, the cells that are being measured)...
thanks