View Full Version : reversing wmprph.exe - the wmp12 richpreviewhandler
xplora
January 3rd, 2011, 01:48
Hi ...
My knowledge is not that good to impliment the change that I want for this program.
Mission is to find the background color used in this program, whick is quite difficult since there are two windows involved here (AtlAxWin, which hosts the skin inside wmploc.dll called RICHPREVIEW.WSZ) and uses COLOR_WINDOW as background color.
This I changed this and it now returns COLOR_3DFACE.
The other window (RPHInnerParent) uses CreateSolidBrush to obtain the Background Color, but using Syy++ from Microsoft it shows that it returns a different color each time a new window is created (but what is the reason for this ?).
The Readingpane in my instance is colored to use ARGB(255, 214, 214, 214) via the msstyles skin which works fine while previewing photos since the color does not get painted over, like with the wmp12 previewhandler who paints it with it's own Brush.
I can prevent it from painting the background by jumping over, but then when the previewpane is sized it does not redraw the color I have ARGB(255, 214, 214, 214) and the white background show again.
The disassembly looks like this :
I guess this is where the action is.
-------------------------------------------------------------------------
loc_1002D3B: ; color
push dword ptr [esi+1Ch]
call ds:CreateSolidBrush
mov [esi+6Ch], eax
mov esi, [esi+28h]
test esi, esi
jz short loc_1002D5C
test eax, eax
jz short loc_1002D5
push eax ; dwNewLong
push 0FFFFFFF6h ; nIndex
push esi ; hWnd
call ds:SetClassLongW
--------------------------------------------------------------------------
This question is probably more suited for a skinning forum but then again they don't discuss dissassebler stuff there
If we can solve this here it would be great.
I can post the changes i've made if that'll clarify the point i'm at now?
Thanks
Kayaker
January 3rd, 2011, 02:45
Hi
I don't quite understand what you're trying to do, but I'll hazard a guess - if you were to patch the CreateSolidBrush call to use your ARGB value, then SetClassLongW should set the new GCL_HBRBACKGROUND to your modified background brush and should be used for the class upon resizing.
Unfortunately 'push dword ptr [esi+1Ch]' is a 3 byte opcode and the new 'push ARGB' would be 5 bytes, so it looks like you'd need a redirected patch.
Is that about the extent of it?
Kayaker
xplora
January 3rd, 2011, 03:43
Yes the Class I think for this window (the one with CreateSolidBrush) does not specify a BackGround Color (COLOR_WINDOW+1) like the other window. So it uses CreateSolidBrush.
xplora
January 3rd, 2011, 03:55
2388
2387
Here are a grab of the window ReadingPane, that shows the two windows with different background colors.
The outer obviously is the one that has to be changed.
From W32Dasm the inner one was changed, but for the outer there
is nothing in RegisterClass to change.
CF 45 EC 06 00 00 00 -> CF 45 EC 10 00 00 00
I changed the 06 (COLOR_WINDOW) to 10 (COLOR_3DFACE).
xplora
January 3rd, 2011, 04:12
2389
All dword pointers ...
xplora
January 3rd, 2011, 05:01
Quote:
[Originally Posted by xplora;88849]2389
All dword pointers ... |
If I insert my code in here and do a jump at the CreateSolidBrush call, it may work I think ...
xplora
January 6th, 2011, 07:27
Yeah i'm in way over my head with this one. Not sure this is ever going to work.
Kayaker, you're right, but I do not have the knowledge to apply a redirected patch.
Everytime th window needs to br updated it Calls CreateSolidBrush and it seems that
brush is never the same - weird!
xplora
January 8th, 2011, 05:45
If only every program was as easy as this (sample program):
in code:
wcex.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
in binary:
:004019CB C744242C10000000 mov [esp+2C], 00000010
But in wmprph.exe the wcex.hbrBackground is disabled according to IDA.
Instead they created a SolidBrush and put it in a class.
So i'm still looking to find out where to change that color (which is white).
I can manage to change it to Black, but that's not nice.
Also manage it to not Paint any color, but wthen the windows is resized,
the color does not get updated and the white again shows.
-----------------------------------------------------------------------
wmprph.exe :
I don't see anything about *wcex.hbrBackground* here?
----------------------------------------------------------------------
* Reference To: USER32.GetClassInfoExW, Ord:010Dh
|
:0100291D FF1548120001 Call dword ptr [01001248]
:01002923 85C0 test eax, eax
:01002925 7563 jne 0100298A
:01002927 A168120001 mov eax, dword ptr [01001268]
:0100292C 68007F0000 push 00007F00
:01002931 56 push esi
:01002932 C745CC30000000 mov [ebp-34], 00000030
:01002939 C745D003000000 mov [ebp-30], 00000003
:01002940 8945D4 mov dword ptr [ebp-2C], eax
:01002943 8975D8 mov dword ptr [ebp-28], esi
:01002946 8975DC mov dword ptr [ebp-24], esi
:01002949 895DE0 mov dword ptr [ebp-20], ebx
:0100294C 8975E4 mov dword ptr [ebp-1C], esi
* Reference To: USER32.LoadCursorW, Ord:01EBh
|
:0100294F FF154C120001 Call dword ptr [0100124C]
:01002955 8945E8 mov dword ptr [ebp-18], eax
:01002958 8D45CC lea eax, dword ptr [ebp-34]
:0100295B 50 push eax
:0100295C 8975EC mov dword ptr [ebp-14], esi
:0100295F 8975F0 mov dword ptr [ebp-10], esi
:01002962 897DF4 mov dword ptr [ebp-0C], edi
:01002965 8975F8 mov dword ptr [ebp-08], esi
* Reference To: USER32.RegisterClassExW, Ord:024Dh
|
:01002968 FF1550120001 Call dword ptr [01001250]
:0100296E 6685C0 test ax, ax
:01002971 7517 jne 0100298A
-----------------------------------------------------------------------
CreateSolidBrush :
-----------------------------------------------------------------------
* Reference To: GDI32.CreateSolidBrush, Ord:0054h
|
:01002D3E FF1560100001 Call dword ptr [01001060]
:01002D44 89466C mov dword ptr [esi+6C], eax
:01002D47 8B7628 mov esi, dword ptr [esi+28]
:01002D4A 85F6 test esi, esi
:01002D4C 740E je 01002D5C
:01002D4E 85C0 test eax, eax
:01002D50 740A je 01002D5C
:01002D52 50 push eax
:01002D53 6AF6 push FFFFFFF6
:01002D55 56 push esi
----------------------------------------------------------------------
Kayaker
January 8th, 2011, 12:36
I still think you need to inject your own code to replace the parameter value pushed to CreateSolidBrush to the one you want.
Google for "code cave" or "Inject code + Notepad" or anything similar to learn about the technique. The concept is simple enough, you need to find a location somewhere close to the CreateSolidBrush call that you can overwrite with a jump to a "code cave" (an unused block of bytes often found at the end of a code section), or create a completely new section in which to write your code.
You then replace the bytes you overwrote so that code still executes, create the new parameter (push ARGB(255, 214, 214, 214)), and jump immediately back to call ds:CreateSolidBrush. The original 'push dword ptr [esi+1Ch]' of CreateSolidBrush is therefore never used.
The following is a handy utility for this, but can be done with other tools as well.
http://www.woodmann.com/collaborative/tools/Code_Snippet_Creator_(Iczelion)
Look into that and come back if you have problems.
xplora
January 9th, 2011, 01:36
That sounds like the best thing to do, I think I can handle it, thanks Kayaker ...
Going to look into it

xplora
January 10th, 2011, 10:37
Quote:
[Originally Posted by Kayaker;88920]I still think you need to inject your own code to replace the parameter value pushed to CreateSolidBrush to the one you want.
Google for "code cave" or "Inject code + Notepad" or anything similar to learn about the technique. The concept is simple enough, you need to find a location somewhere close to the CreateSolidBrush call that you can overwrite with a jump to a "code cave" (an unused block of bytes often found at the end of a code section), or create a completely new section in which to write your code.
You then replace the bytes you overwrote so that code still executes, create the new parameter (push ARGB(255, 214, 214, 214)), and jump immediately back to call ds:CreateSolidBrush. The original 'push dword ptr [esi+1Ch]' of CreateSolidBrush is therefore never used.
The following is a handy utility for this, but can be done with other tools as well.
http://www.woodmann.com/collaborative/tools/Code_Snippet_Creator_(Iczelion)
Look into that and come back if you have problems. |
I'll be using this code:
"invoke CreateSolidBrush,00FF8888h"
Is this the correct way?
I'm going to try the notepad tutorial first, just to get the feel for it,
since i'm not getting the jumps right.
thanks.
Kayaker
January 10th, 2011, 18:37
Quote:
[Originally Posted by xplora;88962]I'll be using this code:
"invoke CreateSolidBrush,00FF8888h"
Is this the correct way?
|
You could do that, but then you'd have to return to the instruction *after* the original CreateSolidBrush call. There's really no need to use the full invoke when all you're doing is changing the one parameter.
I think you'd only need something like this.
Code:
pushad
pushfd
// execute overwritten instructions where you patched in the jump
// and any other code that needs to run
push 00FF8888h
popfd
popad
jmp to original call ds:CreateSolidBrush
Note the bracketing push*/pop* instructions. Not strictly necessary with this simple patch, but it's usually a good idea to preserve the original registers and perhaps the flags within your patch (unless of course they *need* to contain new values for subsequent code to execute correctly).
Note something else here, if you used the full invoke CreateSolidBrush in the patch, you'd also have to execute the
mov [esi+6Ch], eax instruction to save the return value from within the patch, and then return to the original code at the instruction following that one.
Why?
Because the popad I suggested using at the end of the patch would restore the old eax before the new return value was saved... gotta be careful
I don't know what the rest of the code looks like or where a good spot is to overwrite with the jump to your patch. Perhaps it might be easier to directly modify the value of [esi+1Ch] at an earlier point and just let the original 'push dword ptr [esi+1Ch]' instruction execute. Whatever works best.
You should make sure that the CreateSolidBrush/SetClassLongW sequence is *only* being used by the window you want to affect. If it's used in a more global scope then you'll have to the check which hWnd is being handled and set an appropriate IF condition.
dELTA
January 10th, 2011, 19:13
Quote:
[Originally Posted by Kayaker;88970]Code: pushad
pushfd
// execute overwritten instructions where you patched in the jump
// and any other code that needs to run
push 00FF8888h
popfd
popad
jmp to original call ds:CreateSolidBrush
|
I might absolutely have missed something completely here, but won't the push/pop sequence before the jump above just corrupt all registers and leave the first (or last, depending on how you see it) four bytes of data produced by the pushad instruction on the stack (thus becoming the value of the
crColor parameter to the
CreateSolidBrush function)?

BanMe
January 10th, 2011, 19:58
Actually the state of execution wouldnt be preserved by those pushes and pops,you are correct.
code should be if executed just prior to call which is the most convient method.
Code:
..somecode i cant see from example here..
pop eax;get old color off of stack ?
push 00FF8888h;
jmp CallToCreateSolidBrush
In the code above only ebp is modified.
If done as xplora suggests after the call this makes the code alot different and provides me a better example to give..
so after the call you have code like this.
Code:
:01002D44 89466C mov dword ptr [esi+6C], eax
:01002D47 8B7628 mov esi, dword ptr [esi+28]
you need 5 of those byte to overwrite with your jump to your code to change color. so you have to write that and nop the remaining bytes.
So in the hook code you would have to duplicate those instructions and return just after your jmp.
that code 'should' look like this:
Code:
pushad
pushfd
mov eax,[ebp+4];that pop would cause same effect you described o0.
push eax
call DeleteObject
popad;restores eax to old handle
popfd;restores any flags set in deleteobject
push 00FF8888h
call CreateSolidBrush
mov dword ptr [esi+6C], eax
mov esi, dword ptr [esi+28]
jmp HookLocation+5(if u nopped it + 6 if not..)
Now I think that is what Kayaker was thinking.. :d
regards BanMe
dELTA
January 10th, 2011, 20:09
Quote:
[Originally Posted by BanMe;88974]Actually the state of execution is preserved by those pushes and pops.
Though they are not 'needed' if you are not modifying any registers or 'flags' with your code, though it is good practice to preserve the state of execution in injected code. |
Yes, I know what the instructions do. What I am referring to is the fact that the stack is not balanced within the injected code ("push 00FF8888h"

before attempting to restore the system state from the stack again, and thus, you restore the wrong data, which in effect rather means
corrupting the contents of
all registers,
and the parameter that you tried to modify in the first place.
If the injected patch would leave the stack balanced, I would absolutely not have any objection, but this injected code doesn't, and thus you'd have to make a
call to the function
before the popfd/popad sequence in this injected code, right? This would of course in turn mean that you eradicate all register modifications that the called function might perform as part of its intended functionality, so no go there either really.
So the solution is to either leave out the register preserving push/pop sequences completely, or to analyze the called function code to see which registers and flags it modifies, and restore all but these, but then you have at the same time eliminated the need for the restoration, since in this analysis you will also see that your own patch code does not modify any of them to begin with.
Damn Kayaker, always trying to mock newbies by fooling them into doing the wrong things, all under the impression of just being a really helpful guy...

BanMe
January 10th, 2011, 20:42
Im sorry I missed 'kayakers' 'push' in the pushad/popad code sequence, and read your reply,but promptly updated to reflect correctness of your statement.. :d(while u wrote 3 paragraphs I was contemplating the 'code'.
A push in any direction that leads to 'others' having to 'think and do thing for themselves' is helpful.. Sorry I might have ruined that..
Kayaker
January 10th, 2011, 22:51
Damn, that's what I get for trying to get across 2 points at the same time. Yeah, it wouldn't crash because the stack would still be balanced overall, but of course the parameter value wouldn't be in the right location on the stack for the CreateSolidBrush call with a full pushad/popad + the isolated push within the patch. Just eliminate the pushad/popad and ignore everything else I say and it should be OK

BanMe
January 10th, 2011, 23:47
Don't listen to him,he has a power level over 9000 ...o0
Also xplora mentions something to the effect that he not sure if changing this brush would change the whole background and not the element he wants.
I will go into this case.
First locate where your control that you want to modify is created,and where the handle is stored.next find the location of the window handle the brush is used on. In the hook code you would need a way to compare the two,and act accordingly.
xplora
January 11th, 2011, 04:24
Hi,
Thanks, it's rather interesting seeing you guys fight it out
But seriously let me give you some more background about what I have done
thus far ...
Inside Wmploc.dll there is a skin file called "RICHPREVIEW.WSZ" which i modified.
It's actually a compiled script but i coud'nt find a way of decompiling it, so i just did
a ASCII mod in it ...
1.4.2.;.r.e.s.:././.w.m.p.l.o.c./.R.T._.T.E.X.T./.#.4.0.0.4.;.r.e.s.:././.w.m.p.l.o.c./.R.T._.T.E.X.T./.#.1.3.2...=.�o.n.l.o.a.d...I.n.i.t.P.r.e.v.i.e.w.O.C.X.S.k.i.n.(.).;......�...b.l.a.c.k...�.. ....p.l.a.y.e.r...W..p.l.a.y.s.t.a.t.e.c.h.a.n.g.e..
I just changed the black to g.r.a.y.. and defined it in this script inside wmploc.dll :
Then there's this script which was not compiled:
//<script>
// Windows Media Player - Copyright 2000 Microsoft Corporation.
var g_albumArtFadingIn = false;
var g_albumArtFadingOut = false;
var gray = "#D6D6D6";
function InitPreviewOCXSkin()
{
UpdateMainPanel();
try {
view.backgroundColor=gray; // Launcher.GetPreviewPaneColor();
}
catch(err) {}
}
------------------------------------------------------------------------------------
And this solved that problem quite easily.
But unfortunately the matter of the outer parent window
is more indepth stuff indeed
btw. I don't know why they bothered
putting "Launcher.GetPreviewPaneColor();" in
since it will always be black anyway.
The whole parent window Class "RPHInnerParent"
behind the the "AtlAxWin" Class one must be
modifiable, damn I WILL find the way of changing
it the inject way!
Thanks.
BanMe
January 11th, 2011, 10:54
The ways to 'doing' things is varied,and the fact it uses scripts means it has to have a script processing ability in there somewhere,if this is the case then it probably has its own COM interface, to which you should look into :}
http://www.askvg.com/customize-windows-media-player-12-wmp12-library-background-image-in-windows-7/
http://msdn.microsoft.com/en-us/library/dd758070%28v=VS.85%29.aspx
Specifically the Object Model and the SDK. You will know more then you need to...xD
regards BanMe
xplora
January 11th, 2011, 11:35
Thanks ,
Yes I'll do that BanMe, I tell you there is so many freaking scripts
in Win7, it makes me
For the ReadingPane there is scripts in *.msstyles, shell32.dll, shellstyle.dll and the
MUI files etc.
I'll focus on my original idea first and then dig around some more.
That guy called UkIntel, did a lot of Hex mods for the Vista interface
and I don't know but there is that ASKVG thing as well as you noted.
But as I said there are many scripts doing the layout, animations
etc.
I'm learning this tutorial at the moment, to get myself familiriazed
whith the Injection method:
http://home.inf.fh-rhein-sieg.de/~ikarim2s/how2injectcode/code_inject.html
regards
xplora
xplora
January 11th, 2011, 15:50
Pretty interesting ...
I had a look on WikiPedia and found a good explanation of these.
I think MSDN published some PreviewHandler samples.
I found this in there:
// Stephen Toub
// Coded and published in January 2007 issue of MSDN Magazine
// http://msdn.microsoft.com/msdnmag/issues/07/01/PreviewHandlers/default.aspx
using System;
using System.Runtime.InteropServices;
namespace C4F.DevKit.PreviewHandler.PreviewHandlerFramework
{
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("8327b13c-b63f-4b24-9b8a-d010dcc3f599"

]
interface IPreviewHandlerVisuals
{
void SetBackgroundColor(COLORREF color);
void SetFont(ref LOGFONT plf);
void SetTextColor(COLORREF color);
}
}
xplora
BanMe
January 11th, 2011, 16:43
I can't tell you, what I enjoy more..research and knowing myself, or helping others to walk there own path. Your curiosity is commendable,continue on, and keep us updated.
regards BanMe
dELTA
January 11th, 2011, 17:13
Quote:
[Originally Posted by Kayaker;88980]Yeah, it wouldn't crash because the stack would still be balanced overall, but of course the parameter value wouldn't be in the right location on the stack for the CreateSolidBrush call with a full pushad/popad + the isolated push within the patch. |
Actually, since the calling code seems to use ebp/esi-based stack frames, it will most likely crash on the first operation accessing a local variable in the calling function, which happens to be the first instruction subsequent to the CreateSolidBrush() call. If you would have "only" unbalanced the stack, it would instead most likely survive until the return from the calling function (or at least until it tries to dereference a pointer stored in one of its local variables), i.e.
longer than with the discussed code.

xplora
January 12th, 2011, 00:33
Code:
pushad ; code: 60 - Push contents of general-purpose registers onto the stack
pushfd ; code: 9C - Decrements the stack pointer by 4 and pushes the entire contents of the EFLAGS register onto the stack
// execute overwritten instructions where you patched in the jump
// and any other code that needs to run
push 00FF8888h ; Decrements the stack pointer and then stores the source operand (color?) on the top of the stack
popfd ; 9D - Pops a doubleword from the top of the stack and stores the value in the EFLAGS register
popad ; code: 61 - Pops doublewords from the stack into the general-purpose registers
jmp to original call ds:CreateSolidBrush
Code:
pushad
pushfd
mov eax,[ebp+4];that pop would cause same effect you described o0.
push eax
call DeleteObject
popad;restores eax to old handle
popfd;restores any flags set in deleteobject
push 00FF8888h ;color
call CreateSolidBrush
mov dword ptr [esi+6C], eax
mov esi, dword ptr [esi+28]
jmp HookLocation+5(if u nopped it + 6 if not..)
Fantastic! allthough to me it's like a overdose of information!
I need time to let this soak in and see the whole picture.
You guys are really good with this stuff, makes my head spin!
Could you help me a little with this:
code: 50 + rd PUSH r32 (push 32 bit register) what is
rd ?
code: 6A PUSH imm8 (8 bit?) what is
imm ?
code: 68 PUSH imm32 (32 bit?)
code: FF /6 PUSH r/m16 (16 bit?) what is
r/m ?
code: FF /6 PUSH r/m32 (32 bit?)
ok I found it here:
http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/ ("http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/")
regards
xplora
BanMe
January 12th, 2011, 11:24
R/m32 means 32 bit register or 32 Bit memory address.
Only by code refs was I able to see that imm32 is congruent to m32 I think...
And +rd I'm not sure...
dELTA
January 12th, 2011, 17:12
Here is another short and summarizing explanation about this common operand notation, to make this thread more complete:
Registers: reg8 denotes an 8-bit general purpose register, reg16 denotes a 16-bit general purpose register, and reg32 a 32-bit one. fpureg denotes one of the eight FPU stack registers, mmxreg denotes one of the eight 64-bit MMX registers, and segreg denotes a segment register. In addition, some registers (such as AL, DX or ECX) may be specified explicitly.
Immediate operands: imm denotes a generic immediate operand. imm8, imm16 and imm32 are used when the operand is intended to be a specific size. For some of these instructions, an explicit specifier might be needed: for example, ADD ESP,16 could be interpreted as either ADD r/m32,imm32 or ADD r/m32,imm8.
Memory references: mem denotes a generic memory reference; mem8, mem16, mem32, mem64 and mem80 are used when the operand needs to be a specific size. Again, a specifier might be needed in some cases: DEC [address] can be ambiguous. You must then specify DEC BYTE [address], DEC WORD [address] or DEC DWORD [address] instead.
Restricted memory references: one form of the MOV instruction allows a memory address to be specified without allowing the normal range of register combinations and effective address processing. This is denoted by memoffs8, memoffs16 and memoffs32.
Register or memory choices: many instructions can accept either a register or a memory reference as an operand. r/m8 is a shorthand for reg8/mem8; similarly r/m16 and r/m32. r/m64 is MMX-related, and is a shorthand for mmxreg/mem64.
BanMe
January 12th, 2011, 17:26
ebp+4 = who knows
ebp-4 = the parameter.. my bad.
and in essence the mov eax,[ebp+4] could be removed, as eax is the handle to the brush.
xplora
January 14th, 2011, 11:44
Hi again ...
If I take a line of code and binary copy it to my codecave,
put in a jump to the codecave address (where I nopped it)
and then put a jump after the codecave code to the original
address (after the jmp to codecave instruction), should the
program run as normal?
Cause i'm trying it and it's not working.
xplora
xplora
January 14th, 2011, 11:59
Ok seemed the address where the two lines of code was nopped
was a jump location for another jump elsewere, so I fixed that
jump's destination address and it worked again ...
Quote:
[Originally Posted by xplora;89069]Hi again ...
If I take a line of code and binary copy it to my codecave,
put in a jump to the codecave address (where I nopped it)
and then put a jump after the codecave code to the original
address (after the jmp to codecave instruction), should the
program run as normal?
Cause i'm trying it and it's not working.
xplora |
BanMe
January 14th, 2011, 12:03
Nvm I see that you fixed it.. gg
xplora
January 14th, 2011, 14:13
Quote:
[Originally Posted by BanMe;89071]Nvm I see that you fixed it.. gg |
Well yes i'm actually getting a color in, but not the right one.
2403
modified section:
Code:
00AD2D26 . 8B46 6C MOV EAX,DWORD PTR DS:[ESI+6C]
00AD2D29 . 897E 1C MOV DWORD PTR DS:[ESI+1C],EDI
00AD2D2C . 85C0 TEST EAX,EAX
00AD2D2E . 74 07 JE SHORT wmprph.00AD2D37
00AD2D30 . 50 PUSH EAX ; /hObject
00AD2D31 . FF15 5C10AD00 CALL DWORD PTR DS:[<&GDI32.DeleteObject>] ; \DeleteObject
00AD2D37 > E9 8BB10000 JMP wmprph.00ADDEC7
00AD2D3C 90 NOP ; |
00AD2D3D 90 NOP ; |
00AD2D3E > FF15 6010AD00 CALL DWORD PTR DS:[<&GDI32.CreateSolidBrush>] ; \CreateSolidBrush
00AD2D44 . 8946 6C MOV DWORD PTR DS:[ESI+6C],EAX
00AD2D47 . 8B76 28 MOV ESI,DWORD PTR DS:[ESI+28]
00AD2D4A . 85F6 TEST ESI,ESI
00AD2D4C . 74 0E JE SHORT wmprph.00AD2D5C
00AD2D4E . 85C0 TEST EAX,EAX
00AD2D50 . 74 0A JE SHORT wmprph.00AD2D5C
00AD2D52 . 50 PUSH EAX ; /Value
00AD2D53 . 6A F6 PUSH -0A ; |Index = GCL_HBRBACKGROUND
00AD2D55 . 56 PUSH ESI ; |hWnd
00AD2D56 . FF15 2812AD00 CALL DWORD PTR DS:[<&USER32.SetClassLongW>] ; \SetClassLongW
00AD2D5C > A1 18E0AD00 MOV EAX,DWORD PTR DS:[ADE018]
In the codecave:
Code:
00ADDEC5 00 DB 00
00ADDEC6 00 DB 00
00ADDEC7 > 8366 6C 00 AND DWORD PTR DS:[ESI+6C],0
00ADDECB . 60 PUSHAD
00ADDECC . 9C PUSHFD
00ADDECD . 58 POP EAX
00ADDECE . 90 NOP
00ADDECF . 68 D6D6D600 PUSH 0D6D6D6
00ADDED4 . 9D POPFD
00ADDED5 . 61 POPAD
00ADDED6 .^ E9 634EFFFF JMP wmprph.00AD2D3E
00ADDEDB 00 DB 00
00ADDEDC 00 DB 00
Yes, Yes, YES!
Got it working, wow!
Code:
005DDEC5 00 DB 00
005DDEC6 00 DB 00
005DDEC7 > 8366 6C 00 AND DWORD PTR DS:[ESI+6C],0
005DDECB . 60 PUSHAD
005DDECC . 9C PUSHFD
005DDECD . 58 POP EAX
005DDECE . 90 NOP
005DDECF . 68 D6D6D600 PUSH 0D6D6D6
005DDED4 . 90 NOP
005DDED5 . 90 NOP
005DDED6 .^ E9 634EFFFF JMP wmprph.005D2D3E
005DDEDB 00 DB 00
005DDEDC 00 DB 00
This is AWESOME

, only thing is, the resizing is not that smooth.
xplora
BanMe
January 14th, 2011, 14:54
Ok so you did start to apply what you've learned, as far as I see you just a few points shy of getting it..I would be glad to help,PM me.(and you 'got' it when i posted..all the good I am..)
you can also remove the pushes :] To make sure of no funky effects.
Code:
AND DWORD PTR DS:[ESI+6C],0
POP EAX
PUSH COLOR
JMPBACK
nop stands for no operation

xplora
January 14th, 2011, 15:28
LOL ..BanMe,
Yeah thanks a lot ...

Very well done.
Those nops will be gone soon.
Seeya
dELTA
January 14th, 2011, 19:40
Congratulations.
And just to clarify what BanMe said above, you should remove the pushad/pushfd since you removed/nop'ed the popfd/popad, otherwise the stack will be unbalanced when you return from the call, which can get you in a lot of trouble sooner or later in the execution path of the program.
BanMe
January 14th, 2011, 20:23
Another thing that caught my attention when rereading the code..
was that the jmp to goto your code cave takes up 7 bytes (5 bytes for jmp and 2 in nops) and the "AND DWORD PTR DS:[ESI+6C],0" is only 4 of those bytes, what where the are other 3 bytes? lol nvm push dword ptr [esi+1ch].. 3 bytes and old color reference I see why not replace now..
xplora
January 15th, 2011, 03:03
Quote:
[Originally Posted by dELTA;89087]Congratulations. 
And just to clarify what BanMe said above, you should remove the pushad/pushfd since you removed/nop'ed the popfd/popad, otherwise the stack will be unbalanced when you return from the call, which can get you in a lot of trouble sooner or later in the execution path of the program. |
I see,
Thank you dELTA.
xplora
January 15th, 2011, 03:12
I just saw this,
Code:
0061DE5C /72 6F JB SHORT wmprph.0061DECD
It jumps to my code?
Code:
0061DECC . 68 D6D6D600 PUSH 0D6D6D6
So I will just redirect the jump to an address further past my code, right?
xplora
January 15th, 2011, 03:18
I must say I like doing "patching" the manual way,
instead of using a program like Code Snippet Creator - since
CSC will just complicate things for me.
And leave you less satisfied

.

dELTA
January 15th, 2011, 09:42
The normal way of performing patching is to first perform the edits in any tool that is as convenient as possible to work/experiment with (IDA/Olly/CSC etc), and then when the patch code is complete, just do a binary diff of the edits you have performed, and package this binary patch as simple and efficient as possible.
IDA even has a built-in feature to generate binary diff files of all your patches for you, which is very convenient.
There are also a bunch of ready-made tools for packaging, storing and distributing patches once they are complete, e.g. these:
http://www.woodmann.com/collaborative/tools/Category:Patch_Packaging_Tools
xplora
February 24th, 2012, 04:20
I know this is more than a year ago this was discussed, but recently
coming back to windows I noticed that this method works, but causes
WerFault.exe (Windows Error Reporting) to run.
Original Code:
Code:
00A62D0A |. 8078 39 05 CMP BYTE PTR DS:[EAX+39],5
00A62D0E |. 72 13 JB SHORT wmprph_b.00A62D23
00A62D10 |. 57 PUSH EDI ; /Arg5
00A62D11 |. 68 8014A600 PUSH wmprph_b.00A61480 ; |Arg4 = 00A61480
00A62D16 |. 6A 20 PUSH 20 ; |Arg3 = 00000020
00A62D18 |. FF70 34 PUSH DWORD PTR DS:[EAX+34] ; |Arg2
00A62D1B |. FF70 30 PUSH DWORD PTR DS:[EAX+30] ; |Arg1
00A62D1E |. E8 2CFBFFFF CALL wmprph_b.00A6284F ; \wmprph_b.00A6284F
00A62D23 |> 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
00A62D26 |. 8B46 6C MOV EAX,DWORD PTR DS:[ESI+6C]
00A62D29 |. 897E 1C MOV DWORD PTR DS:[ESI+1C],EDI
00A62D2C |. 85C0 TEST EAX,EAX
00A62D2E |. 74 0B JE SHORT wmprph_b.00A62D3B
00A62D30 |. 50 PUSH EAX ; /hObject
00A62D31 |. FF15 5C10A600 CALL DWORD PTR DS:[<&GDI32.DeleteObject>>; \DeleteObject
00A62D37 |. 8366 6C 00 AND DWORD PTR DS:[ESI+6C],0
00A62D3B |> FF76 1C PUSH DWORD PTR DS:[ESI+1C] ; /Color
00A62D3E |. FF15 6010A600 CALL DWORD PTR DS:[<&GDI32.CreateSolidBr>; \CreateSolidBrush
00A62D44 |. 8946 6C MOV DWORD PTR DS:[ESI+6C],EAX
00A62D47 |. 8B76 28 MOV ESI,DWORD PTR DS:[ESI+28]
00A62D4A |. 85F6 TEST ESI,ESI
00A62D4C |. 74 0E JE SHORT wmprph_b.00A62D5C
00A62D4E |. 85C0 TEST EAX,EAX
00A62D50 |. 74 0A JE SHORT wmprph_b.00A62D5C
00A62D52 |. 50 PUSH EAX ; /Value
00A62D53 |. 6A F6 PUSH -0A ; |Index = GCL_HBRBACKGROUND
00A62D55 |. 56 PUSH ESI ; |hWnd
00A62D56 |. FF15 2812A600 CALL DWORD PTR DS:[<&USER32.SetClassLong>; \SetClassLongW
00A62D5C |> A1 18E0A600 MOV EAX,DWORD PTR DS:[A6E018]
Code cave:
Code:
00A6DF3C 00 DB 00
00A6DF3D 00 DB 00
00A6DF3E 00 DB 00
00A6DF3F 00 DB 00
00A6DF40 00 DB 00
00A6DF41 00 DB 00
00A6DF42 8366 6C 00 AND DWORD PTR DS:[ESI+6C],0
00A6DF46 58 POP EAX
00A6DF47 68 D6D6D600 PUSH 0D6D6D6
00A6DF4C ^E9 ED4DFFFF JMP wmprph_b.00A62D3E
00A6DF51 00 DB 00
00A6DF52 00 DB 00
00A6DF53 00 DB 00
00A6DF54 00 DB 00
00A6DF55 00 DB 00
00A6DF56 00 DB 00
00A6DF57 00 DB 00
Thing is where to put the jump in to the Code cave Address
00A6DF42 - there is only space for 4 bytes and it will
require 5 bytes?
xplora
February 25th, 2012, 11:20
Hi Again,
This is really a crude way of obtaining a result - but it worked without errors! - even
without a codecave ...
Code:
00FD2D1E |. E8 2CFBFFFF CALL wmprph.00FD284F ; \wmprph.00FD284F
00FD2D23 |> 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
00FD2D26 |. 8B46 6C MOV EAX,DWORD PTR DS:[ESI+6C]
00FD2D29 |. 90 NOP
00FD2D2A |. 90 NOP
00FD2D2B |. 90 NOP
00FD2D2C |. 90 NOP
00FD2D2D |. 90 NOP
00FD2D2E |. 90 NOP
00FD2D2F |. 90 NOP
00FD2D30 |. 50 PUSH EAX ; /hObject
00FD2D31 |. FF15 5C10FD00 CALL DWORD PTR DS:[<&GDI32.DeleteObject>] ; \DeleteObject
00FD2D37 |. 90 NOP
00FD2D38 |. 90 NOP
00FD2D39 |. 68 60606000 PUSH 606060 ; /Color = RGB(96.,96.,96.)
00FD2D3E |. FF15 6010FD00 CALL DWORD PTR DS:[<&GDI32.CreateSolidBrush>] ; \CreateSolidBrush
00FD2D44 |. 8946 6C MOV DWORD PTR DS:[ESI+6C],EAX
00FD2D47 |. 8B76 28 MOV ESI,DWORD PTR DS:[ESI+28]
00FD2D4A |. 85F6 TEST ESI,ESI
00FD2D4C |. 74 0E JE SHORT wmprph.00FD2D5C
00FD2D4E |. 85C0 TEST EAX,EAX
00FD2D50 |. 74 0A JE SHORT wmprph.00FD2D5C
00FD2D52 |. 50 PUSH EAX ; /Value
00FD2D53 |. 6A F6 PUSH -0A ; |Index = GCL_HBRBACKGROUND
00FD2D55 |. 56 PUSH ESI ; |hWnd
00FD2D56 |. FF15 2812FD00 CALL DWORD PTR DS:[<&USER32.SetClassLongW>] ; \SetClassLongW
00FD2D5C |> A1 18E0FD00 MOV EAX,DWORD PTR DS:[FDE018]
00FD2D61 |. 5F POP EDI
00FD2D62 |. 5E POP ESI
00FD2D63 |. 3BC3 CMP EAX,EBX
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.