Cómo hacer amigos .NET e IDA Pro (sobre la amistad de C # y C ++)



Saludos,



Primero, sobre el problema / tarea: cuando

comencé a escribir otro complemento de depuración para la plataforma retro en IDA Pro (en secreto: será SNES), me encontré con el siguiente conjunto que necesitaba ser amigos:



  1. El kernel del emulador está escrito en C ++ y compilado en una DLL
  2. La GUI del emulador está escrita en C # y usa una DLL del kernel para controlar la emulación
  3. IDA Pro, , C++ DLL ( C++)


- IDA ( , , ..) , IDA .



( ), :



1) LoadLibrary("emu_core.dll"), GetProcAddress(core, "Pause") pause(), , , .



: — ( , GUI )! , , , , DLL-, , , UI, .



, DLL- IDA, . .



2) - -, , — GUI, RPC-.



, :



  • IDA (, , reset), .. , , , .
  • . , , , , RPC .




COM. , , RPC . , , WinAPI (.. C/C++) — C#.



.. GUI , . COM-.



:



1) , COM, [ComVisible(true)]. , - , ( , , )



2) , , ( IDA). ( ComVisible):



[Guid("7710855F-D37B-464B-B645-972BAB2706D4")]  // Visual Studio    GUID-  
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComVisible(true)]
public interface IDebugApi


3) , DebugCOM:



[Guid("6AF9F5DD-6626-4E35-BEF4-29A73E18A739")]
[ComVisible(true)]
public class DebugCOM : IDebugApi


4) ( ) (Class Library), . DebugCOM.dll



5) tlbexp.exe Visual Studio ( Developer Command Prompt) DLL TLB. , ..



:



tlbexp DebugCOM.dll /out:DebugCOM.tlb


COM, :



Assembly exported to 'DebugCOM.tlb'


, . :



TlbExp
TlbExp : warning TX801311B0 : Type library exporter warning processing 'AddressInfo.Type, DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'InteropBreakpoint.MemoryType, DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.GetMemorySize(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.GetMemoryValue(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.SetMemoryValue(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.SetMemoryValues(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.SetMemoryState(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.GetMemoryState(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.GetMemoryAccessCounts(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.
TlbExp : warning TX801311B0 : Type library exporter warning processing 'IDebugApi.GetMemoryAccessCounts2(type), DebugCOM'. Warning: Non COM visible value type 'SnesMemoryType' is being referenced either from the type currently being exported or from one of its base types.


, SnesMemoryType ComVisible(true). .



6) TLB- (File->View TypeLib...) ComView. :



c:\Windows\Microsoft.NET\Framework\v4.0.30319\ComView.exe


IDL:





File->Save as... IDL-.



7) IDL- C++ , , , DebugCOM:







8) IDL- Compile Ctrl+F7. , : DebugCOM_h.h DebugCOM_i.c. ( ), .





, C# , . C/C++. C#.



9) - .h .c , , . :



COM C++
#include <atlbase.h>
#include <iostream>

#include "DebugCOM_h.h"
#include "DebugCOM_i.c"

int main(int argc, char* argv[]) {
    HRESULT hr;

    hr = ::CoInitializeEx(0, COINITBASE_MULTITHREADED);
    if (FAILED(hr))
    {
        std::cout << "CoInitializeEx failure: " << std::hex << std::showbase << hr << std::endl;
        return EXIT_FAILURE;
    }

    CLSID CLSID_server;
    hr = ::CLSIDFromString(L"{6AF9F5DD-6626-4E35-BEF4-29A73E18A739}", &CLSID_server);
    if (FAILED(hr))
    {
        std::cout << "CLSIDFromString failure: " << std::hex << std::showbase << hr << std::endl;
        return EXIT_FAILURE;
    }

    CComPtr<IDebugApi> server;

    hr = ::CoCreateInstance(CLSID_server, nullptr, CLSCTX_LOCAL_SERVER, __uuidof(IDebugApi), (void**)&server);
    if (FAILED(hr))
    {
        std::cout << "CoCreateInstance failure: " << std::hex << std::showbase << hr << std::endl;
        return EXIT_FAILURE;
    }

    DebugState state = {};
    hr = server->GetState(&state);
    if (FAILED(hr))
    {
        std::cout << "GetState failure: " << std::hex << std::showbase << hr << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << "PC Address: " << std::hex << std::showbase << state.Cpu.PC << std::endl;

    ::CoUninitialize();

    return EXIT_SUCCESS;

    return 0;
}


COM.



COM-



:



  1. Inprocess
  2. Out-of-process


  • , COM , . , COM GUI, IDA.

    COM DLL.



  • , COM- . , , , -. .. , COM .





, out-of-process COM. , GitHub " " : https://github.com/dotnet/samples/tree/master/core/extensions/OutOfProcCOM. .





Como resultado, logré hacer que IDA Pro y la aplicación .NET Framework fueran amigos de las herramientas de Windows, sin preocuparme por las bicicletas de mis propios protocolos RPC. Además, resolví el problema de tener solo una copia del kernel del emulador y compartir su estado entre varias aplicaciones.




All Articles