Log in

View Full Version : CSP patching problem


Hero
April 15th, 2008, 23:27
Hi all,I'mback again by some question...
Perhaps everybody knows what is CSP and how we need to sign it by Micro$oft.
For testing proposes we can patch CryptAcquireContext in advapi32.dll,in order to disabling sign check,so every CSP will be assumed to be a valid one.
After I saw this patching, I decided to patch it in another way, it means I decided to check CSP dll names too then only bypass CSP checking if the names are identical.
I add my codes to advapi32.dll(expanded .text section Virtual Size and used unused space there) and still everything is OK,But it still needs a JMP command to jump into my codes from main codes of advapi32.dll. OK, at first I tried this JMP patching in memory. I have been boot up computer and run my little test program in olly and patched codes in advapi32.dll to jump into my codes.
hurray!!!everything is ok!!!k,now its time to do SAME patch staticaly in advapi32.dll for using it... OK,I patch it and reboot computer.....
What happened? Computer is not booting up!!!!
it seems half of driver and services are starting,but computer stops booting up(almost near time you need to see logon window).
OK,now what we have?
1-adding some code at end of .text section of advapi32.dll makes no problem and computer boots up.
2-patching needed JMP to our added code in memory make no problem and everything runs normally.
3-patching needed JMP to our added code staticaly prevents computer boot up.
4-in simple tutorial I seen that bypass every CSP validation(it is attached), we do patching statically too, but computer boots up with no problem in that patching...
OK,now what you think about this problem?Why computer is not booting up after my patching?

Note:My OS is Windows XP SP2

Regards

naides
April 16th, 2008, 03:57
Hero:
A few suggestions:
Try making some inconsequential changes in advapi32.dll header, and in the code segment (Change a single letter in the string "This program cannot be run in DOS mode" or an alignment byte between functions, see if windows boots. You will figure out if the problem is an integrity check for advapi32 code or a specific side effect of your patch/injected code that only happens at boot time.

Check if the boot failure produces a crash dump. If so, analyze it with windbg. It may point out the module and the instruction that crashed your little injected code.
See if you system with the modif advapi32 boots in safe mode or in boot log mode. At least you will see the last driver(s)/modules that loads before the boot up freeze, which are likely to be the ones not liking your improved advapi32.

Finally lateral thinking solution: leave the original advapi32.dll alone at boot time then code a little program that renames it to "advapi32.dll.spare", replaces it with your modif advapi32.dll, and runs automatically at the end of the boot sequence. But, someone else has to restore advapi32 to its original self at powerdown or after a crash.

Hero
April 16th, 2008, 05:02
Quote:
[Originally Posted by naides;74002]Hero:
A few suggestions:
Try making some inconsequential changes in advapi32.dll header, and in the code segment (Change a single letter in the string "This program cannot be run in DOS mode" or an alignment byte between functions, see if windows boots. You will figure out if the problem is an integrity check for advapi32 code or a specific side effect of your patch/injected code that only happens at boot time.

i think if it was an integrity check, then the patch that is learnt in tutorial should not boot pc too,isn't it?in addtion i tried to do my patch really near to patch in tutorial(position only defers in 1 ASM instruction).
Quote:
[Originally Posted by naides;74002]Check if the boot failure produces a crash dump. If so, analyze it with windbg. It may point out the module and the instruction that crashed your little injected code.

if from crash you mean getting BSOD,i don't get it,and OS ALMOST boots up.
for example mouse driver comes up and mouse works well,it seems system stops working right before reaching Login Window(no crash,only stopping completely... :P)
Quote:
[Originally Posted by naides;74002]See if you system with the modif advapi32 boots in safe mode or in boot log mode. At least you will see the last driver(s)/modules that loads before the boot up freeze, which are likely to be the ones not liking your improved advapi32.

i have checked boo logs,but i couldn't find out something usefull from it.
Quote:
[Originally Posted by naides;74002]Finally lateral thinking solution: leave the original advapi32.dll alone at boot time then code a little program that renames it to "advapi32.dll.spare", replaces it with your modif advapi32.dll, and runs automatically at the end of the boot sequence. But, someone else has to restore advapi32 to its original self at powerdown or after a crash.

you cannot do this.you can replace advapi32.dll(and canel SFC too in order to keep files),but this change only affect system after computer reboots.

I can provide you with my tampered advapi32.dll if you like.you can check if you find somethign special in it...

Regards

naides
April 16th, 2008, 13:40
Quote:
[Originally Posted by Hero;74004]
I can provide you with my tampered advapi32.dll if you like.


Please do. It should be small enough to fit on a add-on zip file to a post or a PM

blurcode
April 16th, 2008, 17:53
Relocations maybe?

Hero
April 16th, 2008, 23:19
Quote:
[Originally Posted by naides;74014]Please do. It should be small enough to fit on a add-on zip file to a post or a PM

k,I attach 2 modified advapi32s that i modified.
The test OS is Windows XP SP2,and please use a virtual machine for testing this and be sure to make a backup before testing this.
'advapi32-1st patch.dll' is the one that I only have been added needed codes.if you change the windows advapi32.dll with this one,your computer boots up.
'advapi32-2nd patch.dll' is the one that has cross jump from main advapi32.dll codes to my added codes.if you change the windows advapi32.dll with this one,your computer doesn't boot up.
The only deference between these 2 dll is at address 77DE8812(offset 77c12):
Code:
Comparing files advapi32-1st patch.dll and ADVAPI32-2ND PATCH.DLL
00017C12: E9 80
00017C13: E9 BD
00017C14: CA E0
00017C15: 05 FD
00017C16: 00 FF
00017C17: 90 FF
00017C18: 90 01

and last thing,if a noob wana replace advapi32.dll:
1-copy and replace adviapi32.dll at windows/system32/dllcache with patched one
2-rename advapi32.dll at windows/system32 (for example to advapi32.bak),then copy patched dll there
3-you will get a warning from SFC,only close it and press 'Yes' when he asks wana keep file or not.
4-reboot computer.

Quote:
[Originally Posted by blurcode]Relocations maybe?

perhaps,not sure about it,but it seems that dll loads in the same address spaces each time...
and another thing:relocations are important when you have cross section immediate addressing,isn't it?in this dll,all important sections(like .text,import table) are merged.

Regards

blurcode
April 17th, 2008, 03:24
Is your added codes the compare with "Test_CSP.dll" using ntdll._strnicmp because that is in the 1rst dll?

dELTA
April 17th, 2008, 04:53
Quote:
[Originally Posted by Hero;74019]perhaps,not sure about it,but it seems that dll loads in the same address spaces each time...
and another thing:relocations are important when you have cross section immediate addressing,isn't it?in this dll,all important sections(like .text,import table) are merged.
No, relocations affect all opcodes that deal with full (32-bit) addresses (disregarding any sections) and (at least cross-section) offsets.

evlncrn8
April 17th, 2008, 06:05
tried updating / fixing the checksum in the pe header for advapi32.dll (checked on my x64 win xp sp1 machine- the dll has a checksum...) ?

Hero
April 17th, 2008, 22:17
Quote:
[Originally Posted by blurcode;74020]Is your added codes the compare with "Test_CSP.dll" using ntdll._strnicmp because that is in the 1rst dll?


yea,but you see that code in both DLLs and it is the one that makes no problem.

Maximus
April 18th, 2008, 08:04
'system' DLLs loads always at the same address in windows (with no ASR), because they are chain-referenced, so usually they can all load at their preferred address. This is especially true for ntdll, which is mapped before anything by the OS.
That's why the common trick of injecting a dll reading your k32 address of loadlibrary and invoking createremote thread on target address work.

relocs are important because it can happen your module uses direct address offsets. Think, for example, of a push [funccallbakaddress]. If you dont reloc it, you crash if loaded address != preferred image base.

try to make a 'nop string' of code, to see if you made some error in the rewritten code, or if it's your jump to cause the problem. If it is your code, you either used a not-relative address somewhere, or believed a system function were loaded where it is not. You should not rely on any other dll function being loaded, because the load sequence of DLL in windows is... evil, at last.

If you check some advapi functions, you will discover that there are some functions that check for EVERY single api they use if the relevant system dll are already loaded as they should, or not -and in case they load them. This probably means M$ got your same problem some day

...it is called dll madness or such, dont remember. However, i too got stuck by it once, and it is not nice learning that in your skin

Hero
April 19th, 2008, 23:06
Quote:
[Originally Posted by Maximus;74039]You should not rely on any other dll function being loaded, because the load sequence of DLL in windows is... evil, at last.


But for example i can be sure that ntdll.dll has been loaded before advapi32.dll(or will be loaded by it),because advapi32.dll is importing ntdll.dll APIs,isn't it?

Regards

Maximus
April 20th, 2008, 06:51
sure. But if he uses any other dll, or a not-relative ref, it could be the problem, since relocations are quite important in a DLL.
this is, for example:
http://blogs.msdn.com/mgrier/archive/2005/06/18/430409.aspx
but i cant find the ref to the original, old article about it, mah.... i'm getting old :P

Hero
April 21st, 2008, 01:59
k,new change....
I removed call to ntdll._nistrcmp,and implement it by assembly,then there is no call to any API in my added code.
But problem still persists, and computer is not booting up after that patch to my added code,thus problem is not because of that API call.
In addtion,all my JMPs are relative,then it doesn't seem relocations have any relation with them.

Regards

dELTA
April 21st, 2008, 03:31
Hero, if there were originally a relocated address at the position where you have written your patch, your patched-in code will be messed up during runtime since it is referenced from the relocation table. That is the most common problem with relocations, rather than your own instructions needing relocation to work.

And did you try a full NOP of your patch yet, and all other suggestions above?

Maximus
April 21st, 2008, 08:27
this reminded something funny about DLLs at runtime with delphi:
http://www.reversing.be/article.php?story=20050804204446290&query=BPL

dELTA
April 21st, 2008, 10:39
A little clarification, that article has nothing to do with "normal" DLL's in Delphi programs, but rather with cracking/reversing Delphi components, which happen to be packaged in a DLL-like way before being compiled (statically linked) into the main exe file during compilation/build of the program.

Nice article though.

Hero
April 21st, 2008, 13:03
Quote:
[Originally Posted by dELTA;74103]Hero, if there were originally a relocated address at the position where you have written your patch, your patched-in code will be messed up during runtime since it is referenced from the relocation table. That is the most common problem with relocations, rather than your own instructions needing relocation to work.

And did you try a full NOP of your patch yet, and all other suggestions above?

hi dELTA
the command that i patched to insert my code was a CMP command,and i think it was this command:
cmp byte ptr [ebp+220],1
so it has no relocations.

i haven't tried nop yet,but i will try it too...

regards

OHPen
May 3rd, 2008, 10:38
Not sure about what you have done yet,
but wouldn't it a possible solution to use a debugger. i slighly remember such products like numega softice and a newer one called syser ? )))

in my opinion it's rather better than guessing around in the wild. break at the first loading of the dll and there you are...

OHPen

Hero
May 8th, 2008, 01:20
Quote:
[Originally Posted by OHPen;74402]Not sure about what you have done yet,
but wouldn't it a possible solution to use a debugger. i slighly remember such products like numega softice and a newer one called syser ? )))

in my opinion it's rather better than guessing around in the wild. break at the first loading of the dll and there you are...

OHPen


hi
I know that both debuggers can be used for kernel debugging,but the problem is that i have never done kernel debugging till now...

Regards

evlncrn8
May 8th, 2008, 01:35
well its kinda the same as ring 3 debugging, just you see ring 0 api's... in your case though the dll is a ring 3 dll, so you shouldn't have that many problems... and there's no real 'fear' coming from kernel debugging .. jump in, get your feet wet.. whats the worst that can happen... ? bsod... and worst worst case.. hosing the system, so maybe use vmware or something first...

popierdulka
May 22nd, 2008, 11:03
i try use ida to your advapi32.dll vresion 2 - as you can see :

77DE880C FF 15 A8 11 DD 77 call ds:NtQuerySystemInformation
77DE8812 E9 E9 CA 05 00 jmp loc_77E45300 ==>

-------------------------------
77E45300 loc_77E45300: ; CODE XREF: SystemFunction035+35j
77E45300 68 20 00 00 00 push 20h
77E45305 E8 22 00 00 00 call sub_77E4532C
77E4530A 54 push esp
77E4530B db 65h
77E4530B 65 73 74 jnb short near ptr word_77E45382
77E4530E 5F pop edi
77E4530F 43 inc ebx
77E45310 53 push ebx
77E45311 50 push eax
77E45312 db 2Eh, 64h
77E45312 2E 64 6C insb

its looks (imho) like something is not OK with this code ?

Hero
June 13th, 2008, 23:34
if you take a look in memeory dump to this piece of code,you can find out what is that.
As i rememebr,i used that CALL technic to push address of a string in stack....
i mean something like this(only a sample):
----
CALL loadinging
db "123.dll",0
loading:
CALL LoadLibraryA
----

Regards

popierdulka
June 14th, 2008, 06:26
Quote:
[Originally Posted by Hero;75141]if you take a look in memeory dump to this piece of code,you can find out what is that.
....
Regards


You are right - i was too lazy (quick) :-)
Just for clear , i have done it again and now it looks OK .

--------------------------------
xor edi, edi
call ds:NtQuerySystemInformation
jmp for_Heros_only ==>
SystemFunction035 endp ; sp-analysis failed

; --------------------------------------------------------------------------
db 2 dup(90h)
; --------------------------------------------------------------------------
; START OF FUNCTION CHUNK FOR Chek_if_i_am_hero

SystemFunction035_ret1: ; CODE XREF: Chek_if_i_am_hero+18j
jnz short loc_77DE8827
cmp [ebp-21Fh], bl
jz SystemFunction035_ret_OK

loc_77DE8827: ; CODE XREF:


; START OF FUNCTION CHUNK FOR SystemFunction035

for_Heros_only: ; CODE XREF: SystemFunction035+35j
push 20h ; strings length
call Chek_if_i_am_hero ; push name_of_Hero_dll
; --------------------------------------------------------------------------
+name_of_Hero_dll db 'Test_CSP.dll',0
; END OF FUNCTION CHUNK FOR SystemFunction035
db 0
+ dd 5 dup(0)

; =============== S U B R O U T I N E ======================================


Chek_if_i_am_hero proc near ; CODE XREF: SystemFunction035+5CB28

arg_8 = dword ptr 0Ch

; FUNCTION CHUNK AT .text:77DE8819 SIZE 000000DC BYTES

mov eax, [esp+arg_8]
push eax ; actual dll name
call near ptr 7C919F6Bh ; ntdll!_strnicmp:
or eax, eax
jz short hero_was_there
add esp, 0Ch
cmp byte ptr [ebp-220h], 1
jmp SystemFunction035_ret1
; --------------------------------------------------------------------------

hero_was_there: ; CODE XREF: Chek_if_i_am_hero+Cj
add esp, 0Ch
jmp SystemFunction035_ret_OK
Chek_if_i_am_hero endp ; sp-analysis failed

---------------------------------------------------

So maybe there are problems with stack ? advapi32 uses so called
"security_check_cookie" on stack and if somethig is wrong stops the process.

Maybe somethig with call ntdll!_strnicmp ? ( stack, registres ?)
For check you can 'nop' this call and see what happen then ?

regards

popierdulka
June 14th, 2008, 15:22
Quote:
[Originally Posted by popierdulka;75144]You are right - i was too lazy (quick) :-)
/...../
Maybe somethig with call ntdll!_strnicmp ? ( stack, registres ?)
For check you can 'nop' this call and see what happen then ?

regards


I am interested in this cos i am digging in this problem too :-)
The possible explenation is that some address are hard coded in boot proces
and if you extend advapi32 other thing have to move => this problem ?
So i have another idea for you - if you are still interested in this ?
As we know there are now two public keys in advapi32.dll so
why not use one of them for your propuse ?

If you are crazy (like I am) - you me try to signe your dll youself :-)
But my idea for you is to use space used by public key no 2 ( it is about
0x88 bytes). We do not need this key (IMO) . So we have place
( about 100 bytes) inside dll without changing length of any section.

regards