Jump to content

PE Tool for creating patches


WildBill

Recommended Posts

I've uploaded the first version of my PE Tool and updated the top post. This tool is for people who understand PE files to a degree (read: it's easy to screw up an executable if you don't know what you're doing). Hopefully, though, it will make it easier for other people to create patches.

Link to comment
Share on other sites


but when KB2183461 was installed the problem recurred.

Will carry out a total reinstall tomorrow, skipping KB2183461 to see if this update causes the problem.

Installing KB2360131 results in the same "Program error" as above when starting "Add and remove programs" in Control Panel.

KB2360131? Wasn't it KB2183461? dubbio.gif

@WildBill: Thanks for the release. You rock! :thumbup

Link to comment
Share on other sites

Good catch. I had applied a patch in 2183461 (MS10-053) in the wrong place. I just released V2 versions of MS10-053 and MS10-071 and updated the links above. If you have 071 installed then you only need to apply the V2 patch for that one: I had to release both because the same file was patched in both (mshtml.dll). I also updated my notes for MS10-053 to reflect the correct code.

Link to comment
Share on other sites

I can't say for certain, but I would expect the code to be very similar, though the locations might vary. I've found from looking at blackwingcat's patches that the code in question was identical between ENU and JPN, though the addresses did differ.

Link to comment
Share on other sites

A new version of my PE Tool is now up: please see the top post for an updated download link. By the way, has anyone tried making any patches from it yet?

I've also posted a patch to MS10-083. This one really has me scratching my head -- it works just fine, but I'm not entirely sure that it even applies to Win2k. Still, there are other benefits (see the beginning of my notes for details).

;==========================================================================
; MS10-083 patches ported to Windows 2000 SP4
;
; The patches to WordPad looked nasty enough that I decided to try getting
; the XP WordPad to run as-is on 2k. This meant having to enhance
; shlwapi.dll a little (see below). The patch also involves ole32.dll, and
; the differences between 2k and XP are so huge that I opted to patch the
; 2k version of ole32.dll instead.
;
; The XP WordPad looks for a newer version of the richedit control, which
; is in msftedit.dll, so that's included.
;
; Making all these changes gets the XP WordPad running on 2k as-is, and
; according to Dependency Walker there shouldn't be any surprises.
;
; All this said, now that I've crawled through all this and made the
; changes, I'm not sure that this security update even applies to 2k.
; Everything seems to revolve around registry settings that tell an app
; if a DLL is safe to load, and the update.inf part of the patch installs
; a handful of new registry settings. It would be nice if someone who
; understands COM on XP can explain what this is supposed to fix. Still,
; the enhancement to shlwapi and the fact that we're now synchronized with
; XP's WordPad should provide some value nonetheless.
;
; The patch says to include xpsp4res.dll, though I have no idea what it does.
; I think it supplies a popup dialog. I'd be lying if I said I understood
; what's going on here from a big-picture perspective.
;==========================================================================

;==========================================================================
; shlwapi.dll
;
; The XP WordPad requires SHRegGetValueW from shlwapi.dll, which 2k doesn't
; have. Managed to add it with the subroutines that it requires and added
; it to the export list. Since I had to add all this, decided to also
; add (and export) SHRegGetValueA for good measure.
;==========================================================================

; -------------------------------------------------------------------------
; RestrictBootMode
;
; Copied mostly as-is, though rearranged to eliminate fragmentation
; -------------------------------------------------------------------------

$70ACEC80:

; -------------------------------------------------------------------------
; RestrictRegType
;
; Copied mostly as-is, though condensed to use all "short" jumps
; -------------------------------------------------------------------------

$70ACECD4:

; -------------------------------------------------------------------------
; FixRegDataW
; -------------------------------------------------------------------------

$70ACE47C:

; -------------------------------------------------------------------------
; NullTerminateRegSzStringW
; -------------------------------------------------------------------------

$70ACED78:

; -------------------------------------------------------------------------
; NullTerminateRegExpandSzStringW
; -------------------------------------------------------------------------

$70ACE000:

; -------------------------------------------------------------------------
; NullTerminateRegMultiSzStringW
; -------------------------------------------------------------------------

$70ACE330:

; -------------------------------------------------------------------------
; SHRegQueryValueW
; -------------------------------------------------------------------------

$70ACE7BC:

; -------------------------------------------------------------------------
; SHRegQueryValueA
; -------------------------------------------------------------------------

$70ACE900:

; -------------------------------------------------------------------------
; ___report_gsfailure
; -------------------------------------------------------------------------

$70ACE674:

$70ACE5F4: ___security_cookie
$70ACE5F8: ___security_cookie_complement

$70A7D3E0: aKernel32_dll_0

$70ACE604: aSetUnhandledExceptionFilter
$70ACE620: aUnhandledExceptionFilter
$70ACE639: aTerminateProcess

; -------------------------------------------------------------------------
; __security_check_cookie
; -------------------------------------------------------------------------

$70ACE7A0:

; -------------------------------------------------------------------------
; FixRegDataA
; -------------------------------------------------------------------------

$70ACE53C:

; -------------------------------------------------------------------------
; NullTerminateRegSzStringA
; -------------------------------------------------------------------------

$70ACEDE8:

; -------------------------------------------------------------------------
; NullTerminateRegExpandSzStringA
; -------------------------------------------------------------------------

$70ACE1C0:

; -------------------------------------------------------------------------
; NullTerminateRegMultiSzStringA
; -------------------------------------------------------------------------

$70ACE3E8:

; -------------------------------------------------------------------------
; SHRegGetValueW
;
; Exported entry 743 in XP
; -------------------------------------------------------------------------

$70ACE9FC:

$70ACEB78: aShreggetvaluew

; -------------------------------------------------------------------------
; SHRegGetValueA
;
; Exported entry 742 in XP
; -------------------------------------------------------------------------

$70ACEBB8:

$70ACEB98: aShreggetvaluea

; -------------------------------------------------------------------------
; ZeroDataOnFailure
; -------------------------------------------------------------------------

$70ACE9C4:

; -------------------------------------------------------------------------
; RestrictArguments
; -------------------------------------------------------------------------

$70ACE980:

; -------------------------------------------------------------------------
; GetProcPtrA
;
; My own routine for getting a proc address
; -------------------------------------------------------------------------

$70ACE650:

8BFF mov edi, edi
55 push ebp
8BEC mov ebp, esp
FF7508 push dword ptr [ebp+8] ; Module name
FF156412A770 call [$70A71264] ; GetModuleHandleA
85C0 test eax, eax
740A jz $yy
FF750C push dword ptr [ebp+$C] ; Proc name
50 push eax ; Module handle
FF151814A770 call [$70A71418] ; GetProcAddress

$yy:

89EC mov esp, ebp
5D pop ebp
C3 ret



;==========================================================================
; ole32.dll
;==========================================================================

$7CF02000: ___security_cookie
$7CF02004: ___security_cookie_complement
$7CF0202C: aSetUnhandledExceptionFilter
$7CF0204C: wKernel32_dll

; -------------------------------------------------------------------------
; __security_check_cookie
; -------------------------------------------------------------------------

$7CF02010:

; -------------------------------------------------------------------------
; GetProcPtrW
;
; My own routine for getting a proc address
; -------------------------------------------------------------------------

$7CF0206C:

8BFF mov edi, edi
55 push ebp
8BEC mov ebp, esp
FF7508 push dword ptr [ebp+8] ; Module name
FF159C12E27C call [$7CE2129C] ; GetModuleHandleW -- ole32 doesn't import GetModuleHandleA
85C0 test eax, eax
740A jz $7CF02088
FF750C push dword ptr [ebp+$C] ; Proc name
50 push eax ; Module handle
FF153012E27C call [$7CE21230] ; GetProcAddress

$yy:

89EC mov esp, ebp
5D pop ebp
C3 ret

; -------------------------------------------------------------------------
; ___report_gsfailure
;
; Adapted it slightly because we need to use GetProcPtrW to get the address
; to SetUnhandledExceptionFilter
; -------------------------------------------------------------------------

$7CF02090:

; -------------------------------------------------------------------------
; CComRegCatalog::GetProcessInfo
; -------------------------------------------------------------------------

$7CE94E15:

6A72 push 72h ; Allocating room for one more member variable

; -------------------------------------------------------------------------
; CComProcessInfo::CComProcessInfo
; -------------------------------------------------------------------------

$7CE97928:

E98BA80600 jmp $7CF021B8
90 nop

$7CF0219C:

unicode <AppIDFlags>, 0


$7CF021B8:

C7450C04000000 mov [ebp+$C], 4 ; cbData
33C0 xor eax, eax
894368 mov [ebx+$68], eax ; Initialize our new member variable to 0
8D450C lea eax, [ebp+$C] ; cbData
50 push eax
8D85F0FDFFFF lea eax, [ebp-$210] ; Src
50 push eax
8938 mov [eax], edi
8D45F8 lea eax, [ebp-8] ; Type
50 push eax
57 push edi ; 0
689C21F07C push $7CF0219C ; Offset of unicode AppIDFlags string -- needs reloc
FF152810E27C call [$7CE21028] ; RegQueryValueExW -- needs reloc
85C0 test eax, eax
7515 jnz $vv
837DF804 cmp [ebp-8], 4 ; Type
750F jnz $vv
837D0C04 cmp [ebp+$C], 4 ; cbData
7509 jnz $vv
8B85F0FDFFFF mov eax, [ebp-$210] ; Src
894368 mov [ebx+68h], eax

$vv:

8D4350 lea eax, [ebx+50h]
50 push eax
6A01 push 1
E92957F9FF jmp $7CE9792E

; -------------------------------------------------------------------------
; wCreateObject
;
; Copied new one as-is; only had to fix jumps and addresses and add relocs
; (verified that it's compatible except for the extra parameter that it takes)
; -------------------------------------------------------------------------

$7CF02208:

; -------------------------------------------------------------------------

; Change the original to act as a wrapper that pushes an extra 0 on the stack
; and calls the new one above

$7CEA59FE:

8BFF mov edi, edi
55 push ebp
8BEC mov ebp. esp
6A00 push 0 ; Extra argument
FF752C push [ebp+$2C]
FF7528 push [ebp+$28]
FF7524 push [ebp+$24]
FF7520 push [ebp+$20]
FF751C push [ebp+$1C]
FF7518 push [ebp+$18]
FF7514 push [ebp+$14]
FF7510 push [ebp+$10]
FF750C push [ebp+$C]
FF7508 push [ebp+$8]
E8E0C70500 call $7CF02208 ; See above
C9 leave
C22800 ret $28


; -------------------------------------------------------------------------
; OleLoadWithoutBinding
;
; Making a copy of the original (from Win2k) and modifying it to accept an
; extra parameter which it will pass to our new wCreateObject. Like above,
; we'll then convert the original to a wrapper that will pass 0 as the
; extra argument.
; -------------------------------------------------------------------------

$7CF024E4: ; Modified copy goes here

$7CEA5540: ; The original was here

8BFF mov edi, edi
55 push ebp
8BEC mov ebp. esp
6A00 push 0 ; Extra argument
FF7518 push [ebp+$18]
FF7514 push [ebp+$14]
FF7510 push [ebp+$10]
FF750C push [ebp+$C]
FF7508 push [ebp+$8]
E889CF0500 call $7CF024E4 ; See above
C9 leave
C21400 ret $14

$7CF02570: aDllVerifyCLSIDIsSafeToLoad

; -------------------------------------------------------------------------
; OleLoad
;
; A little extra code that gets a proc pointer which we push as an extra argument
; to a call to our new OleLoadWithoutBinding
; -------------------------------------------------------------------------

$7CE58F36:

jmp $7CF02590 ; Jump to our new version

$7CF02590: ; New one is here, copied as-is with addresses fixed up

; -------------------------------------------------------------------------
; CComProcessInfo::GetSaferTrustLevel
; -------------------------------------------------------------------------

$7CF025E4:

B805400080 mov eax, $80004005 ; Signals that it's untrusted
C20800 ret 8

; -------------------------------------------------------------------------
; CComProcessInfo::GetAppIDFlags
; -------------------------------------------------------------------------

$7CF025F0:

8BFF mov edi, edi
55 push ebp
8BEC mov ebp. esp
8B4508 mov eax, [ebp+8] ; arg_0
8B4068 mov eax, [eax+$68] ; We put the AppID flags here
8B4D0C mov ecx, [ebp+$C] ; arg_4
8901 mov [ecx], eax
33C0 xor eax, eax
5D pop ebp
C20800 ret 8

$7CF0260C: _IID_IComProcessInfo2

$7CF0261C: _IID_IComProcessInfo3

; Moving a Unicode string to make roon for more entries in the IComProcessInfo
; VMT array. This will let us support IComProcessInfo3, which can return AppID
; flags.

$7CF02634: aRegistryMach_0

$7CE97E69:

mov [ebp-4], $7CF02634 ; New string location

$7CE25DA0:

0DAFE77C dd $7CE7AF0D ; Offset CServerSecurity::Cancel
E425F07C dd $7CF025E4 ; Offset CComProcessInfo::GetSaferTrustLevel
F025F07C dd $7CF025F0 ; Offset CComProcessInfo::GetAppIDFlags

; -------------------------------------------------------------------------
; CComProcessInfo::QueryInterface
;
; The new code to retrieve the AppID flags won't ever get invoked unless
; we signal that it's available. This means responding that we implement
; IID_IComProcessInfo3 (and IID_IComProcessInfo2 by inclusion). The easiest
; way to do this is to just copy the entire QueryInterface routine and
; redirect the old one to this one and fix up addresses, etc.
; -------------------------------------------------------------------------

$7CF02660: ; New one goes here

$7CE97A02: ; Original was here

E959AC0600 jmp $7CF02660
90 nop

; -------------------------------------------------------------------------
; OleLoadFromStream
;
; Extra code that does a similar check to the patches above
; -------------------------------------------------------------------------

$7CE60C25:

sub esp, $24 ; Add room for a GUID

$7CE60C5B:

E9981A0A00 jmp $7CF026F8
90 nop

$7CF026F8:

8BF0 mov esi, eax
85F6 test esi, esi
7465 jz $nn6
50 push eax
FF159C12E27C call [$7CE2129C] ; GetModuleHandleW
85C0 test eax, eax
745A jz $nn6
687025F07C push $7CF02570 ; offset aDllVerifyCLSIDIsSafeToLoad
50 push eax
FF153012E27C call [$7CE21230] ; GetProcAddress
85C0 test eax, eax
744A jz $nn6
33C9 xor ecx, ecx ; Zero out our new GUID
894DDC mov [ebp-$24], ecx
894DE0 mov [ebp-$20], ecx
894DE4 mov [ebp-$1C], ecx
894DE8 mov [ebp-$18], ecx
8D4DDC lea ecx, [ebp-$24] ; Our new GUID
51 push ecx
8D4DEC lea ecx, [ebp-$14] ; pclsid
51 push ecx
FFD0 call eax
8BF0 mov esi, eax
81FE05000780 cmp esi, $80070005
7528 jnz $nn6
6A04 push 4
59 pop ecx
56 push esi
57 push edi
8D7DDC lea edi, [ebp-$24] ; Our new GUID
BE5844E37C mov esi, $7CE34458 ; offset GUID_NULL
33C0 xor eax, eax
F3A7 repe cmpsd
740E jz $rr3
8D75DC lea esi, [ebp-$24] ; Our new GUID
8D7DEC lea edi, [ebp-$14] ; pclsid
A5 movsd
A5 movsd
A5 movsd
A5 movsd
5F pop edi
5E pop esi
EB07 jmp $nn6

$rr3:

5F pop edi
5E pop esi
E963E5F5FF jmp $7CE60CC6


$nn6:

E9F9E4F5FF jmp $7CE60C61

Link to comment
Share on other sites

@WildBill:

It's a known fact that all official MS cumulative security updates to IE6SP1 (except a couple of rather old ones) work OK in Win 9x/ME

So I suggested testing your unofficial KB2360131 in the proper thread named (somewhat misleading) Latest MS IE6 Security Update Breaks Windows 98?, and bingo! Your update was tested and found to work, too! So, in fact, for the IE6 updates, you now have a somewhat wider user base.

However, while testing the update, Dave-H found out the puzzling fact that the modded mshtmled.dll v. 6.0.2800.1107 file you included in the unofficial update seems to be, in fact, based in the original IE6SP1's v. 6.0.2800.1106, instead of being based in the much newer v. 6.0.2800.1501 or, preferably, the 6.0.2800.1502 (the qfe branch file), both from KB896156... Have you perhaps missed it?

Well, in any case, this post is not only to discuss this point, but also to invite you to join us in discussing those updates in the above mentioned thread.

Keep on the great work, you do rock! :thumbup

As an afterthought, I'd very much appreciate if you could port your mods also to the qfe branch of MSHTML.DLL (i.e.: v. 6.0.2800.1650, thus creating v. 6.0.2800.1652) since it appears to me, on closer inspection, that your modded file is derived from v. 6.0.2800.1649 (i. e.: the gdr branch) of MSHTML.DLL. Some users, like myself, do always prefer qfe branch files (except, of course, when the gdr works but the qfe doesn't, although it never happened to me). Browseui.dll and Shdocvw.dll from both branches are identical, so, for those two, no extra effort is required.

I followed the link but there doesn't seem to be a way to download a version for Win2k :blink:

Link to comment
Share on other sites

Ok, I'll look at it when I get a chance. In the meantime, I've posted an update for MS10-074. It's the MFC library update and uses the new files as-is. While it was easy to put together, i wanted to take some time to make sure that they were compatible with 2k instead of just blindly posting it. I've made some comparisons with the 2k version and also compared the original XPSP3 version with the ones in 2k and XPSP2. The original XPSP3 one turned out to be identical to the one in XPSP2, which was a good sign of compatibility. I didn't see any glaring issues with my brief assembler comparison with the 2k one, and Dependency Walker didn't spot any problems. The update also seems to run fine in my VM, so I guess it's okay. I now have it installed in my main OS installation and I'm seeing no problems.

Link to comment
Share on other sites

I've uploaded a V3 of MS10-071 that uses the newest mshtmled.dll for 2k. It's based on the QFE version, but for good measure I compared the QFE and GDR versions and they're identical save for internal build timestamps. Anyhow, now it has the latest and greatest version inside.

Link to comment
Share on other sites

Wow! Thanks a lot, WildBill, you do rock! :thumbup

BTW, I hadn't compared the QFE and GDR binaries, in this case. But, in fact this may happen, since all MS says about QFE is that they *may* contain additional fixes (however, when they don't, they ought to have the same version number as the corresponding GDR file -- and that usually happens -- but not here)... :wacko:

Link to comment
Share on other sites

Hi WildBill.

Have you tried to use my security patch ? (It doesn't include ole32.dll)

MS10-083

I'm taking a look at MS10-083, but I'd like to see if I can take a different tack. The patch involves changes to ole32.dll and wordpad.exe. When I try to run the XP WordPad it says that it can't find a routine in shlwapi that XP has but 2k presumably doesn't. It might be possible to add the necessary routines to the 2k version so the XP WordPad can be used as-is. I don't know if this is possible or worth it, but I'm looking into it.

And PE Tool 0.0.2 has a critical bug.

*Add Exported function.

*select the added cell.

*Add Exported function name.

*save.

*theb function export table is broken !

(I tried with kernel32.dll)

Edited by blackwingcat
Link to comment
Share on other sites

  • 2 weeks later...

Tomorrow a raft of patches comes out, so I figure I'd write an update of what I'm working on. I'm testing a patch for MS10-048 that also adds some 32-bit icon support to 2k (you'll still need Daedalus to for full support, in fact I'll have to release a new one because the update breaks compatibility somewhat, but Daedalus won't have to interfere as much now). I'm analyzing MS10-073 at the moment, which was one of the holes that Stuxnet exploited. After that I plan to look at what's new this month.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...