I think it's worth figuring out why native does it like this.
Believe me, I've been trying to. I'm only inferring that it should be loaded because using native wintrust calls CryptSIPLoad, and my implementation makes it continue on to call other functions that seem reasonable in that context.
I don't know what tests I can write to show that I should not pass the DLL's function pointers directly back to the caller. That might make sense if crypt32 were to try to unload unused function pointers periodically, since the API doesn't provide an unload function - but that seems overly complicated, and I unload them at DLL unload time instead.
If you have suggestions on tests I can write, I'm all ears.
Also the dll loading part of the patch is quite confusing, hopefully doing it closer to the native way would help make it clearer.
The complication comes from the fact that the registry allows one to have a separate DLL for each function in a SIP, but CryptAddSIPProvider does not. I therefore fail if the DLL names are different. This allows me to use an HMODULE as the hSIP member of a SIP_DISPATCH_INFO, rather than invent some more complicated scheme.
I can add more comments to try to explain that if you like. --Juan
____________________________________________________________________________________ Bored stiff? Loosen up... Download and play hundreds of games for free on Yahoo! Games. http://games.yahoo.com/games/front
On 6/1/07, Juan Lang juan_lang@yahoo.com wrote:
I think it's worth figuring out why native does it like this.
Believe me, I've been trying to. I'm only inferring that it should be loaded because using native wintrust calls CryptSIPLoad, and my implementation makes it continue on to call other functions that seem reasonable in that context.
I don't know what tests I can write to show that I should not pass the DLL's function pointers directly back to the caller. That might make sense if crypt32 were to try to unload unused function pointers periodically, since the API doesn't provide an unload function - but that seems overly complicated, and I unload them at DLL unload time instead.
If you have suggestions on tests I can write, I'm all ears.
I'm trying to come up with more tests but unfortunately no luck yet. I've added some extra calls in the sip.c tests (with native CRYPT32 and msasn1) that directly call the returned pointer:
SetLastError(0xdeadbeef); si.cbSize = sizeof(SIP_SUBJECTINFO); si.pgSubjectType = &unknown; ret2 = sdi.pfGet(&si, &a, 0, &b, &msg); trace("ret : %d, GLE : 0x%08x\n", ret, GetLastError());
ret2 = funcCryptSIPGetSignedDataMsg(&si, &a, 0, &b, &msg); trace("ret : %d, GLE : 0x%08x\n", ret, GetLastError());
Both run the function from crypt32 and forward to wintrust as can be seen from the trace (+snoop,+wintrust):
fixme:wintrust:CryptSIPGetSignedDataMsg (0x33fdb4 0x33fe44 0 0x33fe40 0x33fe4b) stub sip.c:341:ret : 1, GLE : 0x0000007a 0009:CALL CRYPT32.CryptSIPGetSignedDataMsg(<unknown, check return>) ret=60309229 fixme:wintrust:CryptSIPGetSignedDataMsg (0x33fdb4 0x33fe44 0 0x33fe40 0x33fe4b) stub 0009:RET CRYPT32.CryptSIPGetSignedDataMsg(0033fdb4,0033fe44,00000000,0033fe40,0033fe4b) retval=00000000 ret=60309229 sip.c:344:ret : 1, GLE : 0x0000007a
I don't see however how we can write a test for this (apart from the one that tells us already that the function pointers are from crypt32).
It appears that the loading part of all the function pointer is done in CryptSIPLoad and the CryptSIPLoad returns the crypt32 function pointers. All referenced crypt32 functions (such as CryptSIPGetSignedDataMsg) seem to retrieve the dll function pointers (as loaded by CryptSIPLoad) and forward to the appropriate DLL.
Doesn't the above method solve you're problem as well?
A trace with a native WINTRUST/CRYPT32/msasn gives:
0009:CALL WINTRUST.CryptSIPGetSignedDataMsg(<unknown, check return>) ret=7c74de52 0009:RET WINTRUST.CryptSIPGetSignedDataMsg(0033fdb4,0033fe44,00000000,0033fe40,0033fe4b) retval=00000000 ret=7c74de52 sip.c:341:ret : 1, GLE : 0x00000006 0009:CALL CRYPT32.CryptSIPGetSignedDataMsg(<unknown, check return>) ret=60309229 0009:CALL WINTRUST.CryptSIPGetSignedDataMsg(0033fdb4,0033fe44,00000000,0033fe40,0033fe4b) ret=7c74de52 0009:RET WINTRUST.CryptSIPGetSignedDataMsg() retval=00000000 ret=7c74de52 0009:RET CRYPT32.CryptSIPGetSignedDataMsg(0033fdb4,0033fe44,00000000,0033fe40,0033fe4b) retval=00000000 ret=60309229 sip.c:344:ret : 1, GLE : 0x00000006
(Both traces lack of information about the first calls as it's done directly to a function pointer).
I will keep investigating.
Cheers,
Paul.
To kick off this first after memorial day weekend: http://x-coverage.com/micro-mini-string-bikinis/
See ya monday!