I've spent some time now trying to use my COM spy build to mimic an object (picstart.dll) so I can watch how it works.

So, I have my server registered, try a simple program to open it, everything works fine.

But when I try using the 'real' program to open my spy, it hangs up. I'm dumping test message data to a file even on DLL_ATTATCH, but see nothing comming out.

Any one have a guess what I could have missed so the program can't find my spy? If I rename it and place the real dll in the same folder, everything works normally.
Posted on 2003-03-13 20:32:20 by Ernie
Err.. this is rapidly starting to sound like reverse engineering....???
Posted on 2003-03-14 01:10:32 by NaN
Exactly. It IS reverse engineering. There's nothing illegal per say in that.

I'm reversing a dll thats part of a free download. Its purpose is to run a piece of hardware I own. The goal is to provide a more user friendly interface to using the hardware, to make the programming process of a PIC microcontroller a "one click" brainless task for others to use.

It will result in the sale of more microcontrollers for Microchip, which is why they provide the free download in the first place.

Sorry, perhaps I should have explained this, but I didn't want to confuse the topic with info that best belongs more in "The Heap."
Posted on 2003-03-14 06:10:21 by Ernie
You've said enough, I just thought i ought to bring it up. I would give any Joe user some trouble if this were to continue publicly, and I try not to be exclusive.

As for your DLL. I would be glad to help, but I *dont* have your DLL. And i dont really want to re-download a new package. Just for a shot in the dark.

:NaN:
Posted on 2003-03-14 13:30:32 by NaN
Nan,

The dll is about 600K. If you would message me your email I'll send it.
Posted on 2003-03-14 18:07:14 by Ernie
Im sure this will be some help ;)

PICSTARTLib; // Picstart 1.0 Type Library


Class Picstart; // Picstart Class
GUID={0F312197-CB40-453B-9775-AEA058CCA34D};
function Program: HResult;
function Verify: HResult;
function ReadDevice: HResult;
function BlankCheck: HResult;
function Erase: HResult;
function Connect: HResult;

Interface IProgrammer; // IProgrammer Interface
GUID={1DA7DC2D-1435-4CA5-9ED1-B5A190810F27};
function Program: HResult;
function Verify: HResult;
function ReadDevice: HResult;
function BlankCheck: HResult;
function Erase: HResult;
function Connect: HResult;

Interface IHardwareTool; // IHardwareTool Interface
GUID={439CBC36-22D4-431C-8E42-389E667D1C30};
function GetDevice(out pDevice:^^IDevice): HResult;
function IsDeviceSupported(pDevice:^IDevice; ulParam:UI4): HResult;

Interface IDevice; // IDevice Interface
GUID={EF44DA63-EEB3-11D3-9D8F-006008368E4D};
function Initialize(pszPart:LPWSTR): HResult;
function Name(out pszPart:^LPWSTR): HResult;
function Family(out pszFamily:^LPWSTR): HResult;
function GetValue(ulKey:UI4; out pValue:^UI4): HResult;
function GetVariantValues(ulKey:UI4; out pEnumData:^^IEnumVARIANT): HResult;
function GetStringValues(ulKey:UI4; out pEnumStrings:^^IEnumString): HResult;
function GetObjectValues(ulKey:UI4; out pEnumObjects:^^IEnumUnknown): HResult;
function EnumerateDevices(out pEnumDevices:^^IEnumDevices): HResult;
function GetListInfo(ListType:UI4; out pNumElements:^INT; out pElementSize:^INT): HResult;
function GetList(ListType:UI4; out pData:^variant): HResult;
function GetPCMInfo(pcmid:UI4; out pPCMInfo:^variant): HResult;
function GetPCMGUID(pcmid:UI4; out pPCMGUID:^variant): HResult;
function GetVariant(ulKey:UI4; pInData:^^variant; out pOutData:^^variant): HResult;

Interface IEnumString;
GUID={00000101-0000-0000-C000-000000000046};
function RemoteNext(celt:UI4; out rgelt:^LPWSTR; out pceltFetched:^UI4): HResult;
function Skip(celt:UI4): HResult;
function Reset: HResult;
function Clone(out ppenum:^^IEnumString): HResult;

Interface IEnumUnknown;
GUID={00000100-0000-0000-C000-000000000046};
function RemoteNext(celt:UI4; out rgelt:^IUnknown; out pceltFetched:^UI4): HResult;
function Skip(celt:UI4): HResult;
function Reset: HResult;
function Clone(out ppenum:^^IEnumUnknown): HResult;

Interface IEnumDevices; // IEnumDevices Interface
GUID={6F3D7845-630C-4426-A960-58883AA3BB58};
function Next(celt:UI4; out rgelt:^^IDeviceTraits; out pceltFetched:^UI4): HResult;
function Skip(celt:UI4): HResult;
function Reset: HResult;
function Clone(out ppenum:^^IEnumDevices): HResult;

Interface IDeviceTraits; // IDeviceTraits Interface
GUID={F6F494A9-8FEA-4498-8C65-9ABD7DCCA654};
function Name(out pszName:^LPWSTR): HResult;
function Limitations(out pEnumLimits:^^IEnumString): HResult;
function PartTypeMask(out pPartTypeMask:^UI4): HResult;
function SupportMask(out pSupportMask:^UI4): HResult;
function BetaSupportMask(out pBetaSupportMask:^UI4): HResult;
function AlphaSupportMask(out pAlphaSupportMask:^UI4): HResult;
function I2kPCMS(out psz:^LPWSTR): HResult;
function I4kPCMS(out psz:^LPWSTR): HResult;
function Family(out psz:^LPWSTR): HResult;
function ProcID(out pProcID:^UI4): HResult;
function I2kBetaPCMS(out psz:^LPWSTR): HResult;
function I4kBetaPCMS(out psz:^LPWSTR): HResult;


This DLL also imports routines from another MPLab dll "MPLBCOMM.DLL"
Import, MPLBCOMM.dll

Ordinal(Hint) Name
00000004 MPLABCommOpen
0000000B MPLABCommSetConfig
00000002 MPLABCommGetConfig
0000000C MPLABCommWriteCommand
0000000D MPLABCommWriteData
00000001 MPLABCommClose
00000005 MPLABCommReadData


There is a wack load of registry stings under a resource called "REGISTRY"... This may be a concern to ensure certain criteria is met as well:
HKCR

{
Picstart.Programmer.1 = s 'Programmer Class'
{
CLSID = s '{0F312197-CB40-453B-9775-AEA058CCA34D}'
}
Picstart.Programmer = s 'Programmer Class'
{
CLSID = s '{0F312197-CB40-453B-9775-AEA058CCA34D}'
CurVer = s 'Picstart.Programmer.1'
}
NoRemove CLSID
{
ForceRemove {0F312197-CB40-453B-9775-AEA058CCA34D} = s 'Programmer Class'
{
ProgID = s 'Picstart.Programmer.1'
VersionIndependentProgID = s 'Picstart.Programmer'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'TypeLib' = s '{27702258-A140-4999-9B99-23BD790F4165}'
}
}
}

HKLM
{
'SOFTWARE'
{
'Microchip'
{
'MPLAB IDE'
{
'ProcAbout'
{
'Picstart'
{
val 'ModulePath' = s '%Module%'
val 'ProductVersion' = s '%Version%'
}
}
}
}
}
}


I've exported the TypeLib for you as well, its attached as a .zip but rename to a .tlb (i didnt compress it). You can use your favourite tlb converterer to take it from here (I like Japheth's work, but you may have your own preferences).

Let me know if you get anything working from this ;)

Enjoy!
:alright:
NaN
Posted on 2003-03-20 23:24:57 by NaN
Thanks Nan. I've already hit the dll with OleView to extract the typelib. And Maurice's Tlb2Inc.exe got me an include file no muss no fuss.

My clone copy seems to work OK when I use my own loading test program, I get a valid interface pointer from CoGetClassObject. But get nothing when I use the MPLAB program to use my dll.

Curiously, if I use my test program to load the real dll, I get back NULL as the interface pointer, but no error is flagged; CoGetClassObject does not return a FAIL hresult.

I don't understand how that could be, but deserves another close look (which I may get time for next week).
Posted on 2003-03-20 23:49:14 by Ernie