I've written c# code for a registry modifying application, but the problem is c# is easily reversible and obfuscators make the program look like malware. So my problem is that I can't find anything close to Registry.SetValue for c++. Any help is appreciated.
I've tried using a c# to c++ tool by tangible but it was bad and it didn't work as expected at all.
I've also tried RegSetValueEx but I think I used it incorrectly.
This is what I tried:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <Windows.h>
using namespace std;
int main()
{
HKEY key;
if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion"), &key) != ERROR_SUCCESS)
{
cout << "unable to open registry";
}
if (RegSetValueEx(key, TEXT("value_name"), 0, REG_SZ, (LPBYTE)"value_data", strlen("value_data")*sizeof(char)) != ERROR_SUCCESS)
{
RegCloseKey(key);
cout << "Unable to set registry value value_name";
}
else
{
cout << "value_name was set" << endl;
}
return 0;
}
Could someone explain what is value_name value_data and how to use it with an example as that is the main thing I'm confused with.
Your best bet is to use RegSetValueEx - all C++ wrappers for the registry are very thin wrappers around the simple C API.
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <Windows.h>
#include <tchar.h>
using namespace std;
int main()
{
HKEY key;
RegOpenKey(HKEY_CLASSES_ROOT, TEXT(""), &key);
LPCTSTR value = TEXT("");
LPCTSTR data = TEXT("");
LONG setRes = RegSetValueEx(key, value, 0, REG_SZ, (LPBYTE)data, _tcslen(data) * sizeof(TCHAR));
RegCloseKey(key);
return 0;
}
this solved it
Related
So im trying to run a .NET C# script in mono , but i get errors of missing assemblies...
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\Mp3ToSpeech.cs(1,14): error CS0234: The type or namespace name `Speech' does not exist in the namespace `System'. Are you missing an assembly reference?
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\Mp3ToSpeech.cs(6,7): error CS0246: The type or namespace name `NAudio' could not be found. Are you missing an assembly reference?
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\SeleniumWebdriver.cs(1,7): error CS0246: The type or namespace name `OpenQA' could not be found. Are you missing an assembly reference?
...
here is my current C++ code
#include <windows.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <sstream>
#include <direct.h>
#include <filesystem>
#pragma comment(lib, "mono-2.0-boehm.lib") // replaced from mono-2.0.lib
#pragma comment(lib, "mono-2.0-sgen.lib") // It is new with GC code library GC from Gnu Compilication
#pragma comment(lib , "MonoPosixHelper.lib")
std::string get_working_path()
{
char temp[260]; // max windows path length
return (_getcwd(temp, sizeof(temp)) ? std::string(temp) : std::string(""));
}
int main(int argc, char* argv[])
{
#pragma region Load and compile the script
std::string Mp3Path = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\ChromeDriverInstaller.cs )";
std::string ProgramPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Program.cs )";
std::string ChromeInstPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Mp3ToSpeech.cs )";
std::string SeleniumWebPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\SeleniumWebdriver.cs )";
//C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
//C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll
//C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
//C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll
//C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll
std::string references = R"(-r:C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
-r:C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll -r:/C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
-r:C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll -r:C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll)";
std::string command = "mcs " + ProgramPath + ChromeInstPath + SeleniumWebPath + Mp3Path + references + R"( -target:library)";
//Compile the script
std::string Command = std::string(R"(cd C:\Program Files (x86)\Mono\bin && )") + command;
system(Command.c_str());
#pragma endregion
#pragma region Init mono runtime
mono_set_dirs("C:\\Program Files (x86)\\Mono\\lib",
"C:\\Program Files (x86)\\Mono\\etc");
//Init a domain
MonoDomain* domain;
domain = mono_jit_init("MonoScriptTry");
if (!domain)
{
std::cout << "mono_jit_init failed" << std::endl;
system("pause");
return 1;
}
//Open a assembly in the domain
MonoAssembly* assembly;
std::string assemblyPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Program.dll)";
assembly = mono_domain_assembly_open(domain, assemblyPath.c_str());
if (!assembly)
{
std::cout << "mono_domain_assembly_open failed" << std::endl;
system("pause");
return 1;
}
//Get a image from the assembly
MonoImage* image;
image = mono_assembly_get_image(assembly);
if (!image)
{
std::cout << "mono_assembly_get_image failed" << std::endl;
system("pause");
return 1;
}
#pragma endregion
#pragma region Run a static method
{
//Build a method description object
MonoMethodDesc* TypeMethodDesc;
const char* TypeMethodDescStr = "Program:StartWebRegister()";
TypeMethodDesc = mono_method_desc_new(TypeMethodDescStr, NULL);
if (!TypeMethodDesc)
{
std::cout << "mono_method_desc_new failed" << std::endl;
system("pause");
return 1;
}
//Search the method in the image
MonoMethod* method;
method = mono_method_desc_search_in_image(TypeMethodDesc, image);
if (!method)
{
std::cout << "mono_method_desc_search_in_image failed" << std::endl;
system("pause");
return 1;
}
//run the method
std::cout << "Running the static method: " << TypeMethodDescStr << std::endl;
mono_runtime_invoke(method, nullptr, nullptr, nullptr);
}
#pragma endregion
#pragma endregion
system("pause");
return 0;
}
Im trying to reference assemblies using -r: , using full path where they are located , but it doesnt work and i still get errors.
I Tried using msbuild , to build .csproj with instead of msc (see my other question Embedding mono in C++ , Could not load file or assembly 'System.Runtime' or one of its dependencies) but it cant call the static method
So my question is how can i reference the assemblies. Is there a easy way to do that in mono if you are using nuget? I saw on the docs that you can call packages using -pkg: if they have a .pc file (which none of .nuget have)
For those who have also problems with this , my problem was that
std::string references = R"(-r:C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
-r:C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll -r:C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
-r:C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll -r:C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll)";
wasnt respecting this format
msc -r:"reference\to\assembly.dll"
it should be in quotes even if the path doesnt have any spaces.
This is a problem only when you want to use full path , as
msc -r:System.Assembly.dll
works fine!
I have the following C++ function from the MyCppLib.h file of a third party library:
int CppFunc(int Index, wchar_t* String, int StringLength);
where the maximum length of String is StringLength. String is returned by the function (out).
I am trying to wrap this in C++/CLI for use in C#. According to this page it looks like StringBuilder should be used to marshall wchar_t* back to C++/CLI.
So I believe the C++/CLI should look something like this:
#include "MyCppLib.h"
using namespace System;
using namespace System::Text;
namespace MyCppCliLib
{
int CppCliFunc(int Index, StringBuilder^ sB, int StringLength) {
return ::CppFunc(Index, ???, StringLength);
}
}
Now, how can I retrieve the wchar_t* from C++ back to StringBuilder^ ? I can't find a good example on the topic...
I believe the C# side would then looks like:
StringBuilder sB = new StringBuilder();
int x = CppCliFunc(2, sB, 4096);
EDITS:
Thanks to all the comments, I finally got something working, it looks like this (don't quote me on it, it's my first steps in C++/CLI):
#include "MyCppLib.h"
#include <string.h>
#include <stdlib.h>
using namespace System;
using namespace System::Text;
namespace MyCppCliLib
{
String^ CppCliFunc(int Index, int StringLength) {
String^ newString="";
wchar_t* wchar = (wchar_t*)calloc(StringLength, sizeof(wchar_t));
if (wchar != NULL) {
int errorInt = ::CppFunc(Index, wchar, StringLength);
newString = gcnew String(wchar);
if(errorInt != 0){
throw gcnew Exception("Error #" + errorInt.ToString());
}
}else{
throw gcnew Exception("Error wchar is null");
}
free(wchar);
return newString;
}
}
I'm trying to get out an array in a pythonic format [numpy or list] form a DLLwritten in c#/c++. This DLL gives out the pointer to the memory and not the evaluated array. How can I access the memory in a FAST way (I wrote the DLL to speedup the code)?
I have used the pythonnet module and i managed to get the memory pointer as a but I'm failing in extracting the memory pointer as an integer or binary and then to get the data of the output vector.
Here the python code:
import numpy as np
import clr
clr.AddReference(R'...\PyDLL.dll')
from PyDLL import StringLibrary
my_instance = StringLibrary()
x = my_instance.arrayShift(np.array([1,2,3,4,5,6,7,8,9,0]).reshape(-1))
And then the C# code
namespace PyDLL
{
public class StringLibrary
{
public static double[] arrayShift(double[] array)
{
int b = array.Length;
double[] newArray = new double[b];
for(int i=0; i<b; i++)
{
newArray[i] = array[b-i-1];
}
return newArray;
}
}
}
I expect that the output x in python is a list or a np array, while now it is a System.Double[] object.
the expected output of x is [0,9,8,7,6,5,4,3,2,1]
Thank you for any help
After many tries and researches, I managed to solve the problem in this way:
Cpp part:
Open Visual Studio, then create a new project (Dynamic-Link Library).
Name the project and add a new file in the project (Header file) and name it with the same project name.
Insert the following code in the header:
// headerName.h - Contains declarations of math functions
#pragma once
#ifdef HEADERNAME_EXPORTS
#define HEADERNAME_API __declspec(dllexport)
#else
#define HEADERNAME_API __declspec(dllimport)
#endif
// Define the functions that will be called using the DLL
extern "C" HEADERNAME_API void funName1(...);
extern "C" HEADERNAME_API void funName2(...);
extern "C" HEADERNAME_API void funName3(...);
...;
In the folder 'Source Files' add a new file with extension .cpp (call it with the same name as the project), then write the function in this .cpp file. Here an example code:
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier COMPULSORY TO ADD
#include "HEADERNAME.h" // COMPULSORY TO ADD
#include lib#1
#include lib#2
#include lib#3
...
using namespace std;
void funName1(...)
{
...
}
void funName2(...)
{
...
}
void funName3(...)
{
...
}
To be able to pass the arrays between python and c++, in my solution, the use of pointers is needed and no return must be used. The output variable is passed as an input variable, initialized in python, using a pointer. In the DLL the memory cells of the output variables are re-wrote and, doing so, when the DLL completes the function, the output is computed and already usable by python without return.
Here an example of how to write a function using pointers for input and output arrays:
void funName(double* inputArray_pointer, double* outputArray_pointer, int extraVariable)
{
double inner_var = 100;
for (int i = 0; i < extraVariable; i++)
{
inner_var = min(inner_var, *(inputArray_pointer+i));
*(outputArray_pointer + i) = inner_var;
}
}
Then rebuild the DLL.
Python part
To use correctly a DLL in the python code, the modules 'ctypes' and 'numpy' must be imported.
Here follows an example of the python code (This will use the example DLL of point (9)):
import numpy as np
import ctypes
cpp_fun = ctypes.CDLL(R'pathToDll/DLLname.dll')
# Define the types of the arguments of the DLL (pointer, int, double, ecc)
cpp_fun.funName.argtypes = [np.ctypeslib.ndpointer(),
np.ctypeslib.ndpointer(),
ctypes.c_int]
# Allocate or define the input variables using numpy or the standard scalar of python (int, float, ecc..)
inputArray = np.array([0,1,2,3,4,5,6,7,8,9,...,1000]).reshape(-1).astype('f8')
outputArray = np.zeros([inputArray.shape[0]])astype('f8')
extraVariable = inputArray.shape[0]
cpp_fun.funName(inputArray, outputArray, extraVariable)
Doing so, in the variable 'outputArray' we will find the result of the calculations performed inside the DLL as a np array structure.
Hi I've been trying to get name of the metro app with the acquired from AppManifest.xml of the respective app. Came to know that SHLoadIndirectString could be used for this purpose. On checking its functionality manually, I couldn't get the result resource. The code snippet goes as below.
#include <iostream>
using namespace std;
#include <Shlwapi.h>
int main(){
LPWSTR output = L"";
LPWSTR input = L"#{Microsoft.BingMaps_2.1.3230.2048_x64__8wekyb3d8bbwe?ms-resource://Microsoft.BingMaps/resources/AppDisplayName}";
int result = SHLoadIndirectString(input, output, sizeof(output), NULL );
cout<<output;
return 0;
}
The return value "result" is always a negative value(changes if I am changing the input string respective to app). Please guide me on my mistake. Thanks.
Got the right answer.
#include <iostream>
using namespace std;
#include <Shlwapi.h>
int main()
{
PWSTR output = (PWSTR) malloc(sizeof(WCHAR)*256);
PCWSTR input = L"#{C:\\Program Files\\WindowsApps\\Microsoft.BingMaps_2.1.3230.2048_x64__8wekyb3d8bbwe\\resources.pri?ms-resource://Microsoft.BingMaps/Resources/AppShortDisplayName}";
int result = SHLoadIndirectString(input, output, 256, NULL );
cout<<output;
return 0;
}
Objective
What I am trying to do is to make a dll from C++(Visual Studio 2012) and call that from C# winform(Visual Studio 2012).
C++ dll is called "Helper.dll".
C# winform is called "WinFormTest.exe".
C++ dll simply connects to a certain web site, and return the html code with cookie string.
Here is my C# code.
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WinFormTest
{
public partial class Form1 : Form
{
[DllImport(#"Helper.dll", EntryPoint="CallTest", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string CallTest(string Url, StringBuilder Cookies);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string path);
enum PlatformTarget { x64, x86 }
PlatformTarget _platformTarget;
string _assPath;
public Form1()
{
InitializeComponent();
_platformTarget = IntPtr.Size == 8 ? PlatformTarget.x64 : PlatformTarget.x86;
_assPath = AppDomain.CurrentDomain.BaseDirectory;
_assPath = Path.Combine(_assPath, _platformTarget.ToString());
bool ok = SetDllDirectory(_assPath);
if (!ok)
{
throw new System.ComponentModel.Win32Exception();
}
}
private void button1_Click(object sender, EventArgs e)
{
StringBuilder _cookies = new StringBuilder();
string html = CallTest("http://www.google.com", _cookies);
}
}
}
There is no big issue with my C# code.
Here is C++ code.
PlusPlusClass.cpp
#include "stdafx.h"
#include "PlusPlusClass.h"
#include "Scraper.h"
#include <vector>
#include <boost/algorithm/string.hpp>
using namespace std;
extern "C" __declspec(dllexport) BSTR CallTest(const char* Url, char Cookies[])
{
std::string html;
try
{
CPlusPlusClass* cpc = new CPlusPlusClass();
std::map<std::string, std::string> cookies;
html = cpc->GetCookies(Url, cookies);
std::string cookieData;
for (std::map<std::string, std::string>::iterator iterator = cookies.begin(); iterator != cookies.end(); iterator++)
{
cookieData += iterator->first;
cookieData += "=";
cookieData += iterator->second;
cookieData += ";";
}
sprintf(Cookies, cookieData.c_str(), 0);
delete cpc;
}
catch (...)
{
}
return ::SysAllocString(CComBSTR(html.c_str()).Detach());
}
Scraper* class2;
CPlusPlusClass::CPlusPlusClass(void)
{
class2 = new Scraper();
}
CPlusPlusClass::~CPlusPlusClass(void)
{
delete class2; --> here, I get the error. The error just kills my C# application.
}
std::string CPlusPlusClass::GetCookies(const char* Url, std::map<std::string, std::string>& Cookies)
{
return class2->DoSomething(Url, Cookies);
}
Here is Scraper.cpp.
Scraper.cpp
#include "stdafx.h"
#include "Scraper.h"
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <curl/easy.h>
// split
#include <vector>
#include <boost/algorithm/string.hpp>
Scraper::Scraper(void)
{
}
Scraper::~Scraper(void)
{
}
std::string Scraper::DoSomething(const char* Url, std::map<std::string, std::string>& Cookies)
{
std::string _retValue;
curl_global_init( CURL_GLOBAL_ALL );
CURL* curl;
CURLcode res;
struct curl_slist* headerlist = NULL;
curl = curl_easy_init();
if (curl)
{
headerlist = curl_slist_append(headerlist, "Accept: */*");
headerlist = curl_slist_append(headerlist, "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_URL, Url);
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &_retValue);
res = curl_easy_perform(curl);
// receive cookies
struct curl_slist* cookies = NULL;
struct curl_slist* nc;
CURLcode ret = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
nc = cookies;
while (nc)
{
std::vector<std::string> split_vector;
boost::split(split_vector, nc->data, boost::is_any_of("\t"));
Cookies.insert( std::pair<std::string, std::string>(split_vector[5], split_vector[6]) ); --> here is the problem, I think.
nc = nc->next;
}
// clean up
curl_slist_free_all(cookies);
curl_easy_cleanup(curl);
curl_slist_free_all(headerlist);
}
curl_global_cleanup();
return _retValue;
}
std::string Scraper::DoSomething2(const char* Url, std::map<std::string, std::string>& Cookies)
{
std::string temp = "some value is not good enough";
std::vector<std::string> split_vector;
boost::split(split_vector, temp, boost::is_any_of("\t"));
Cookies.insert( std::pair<std::string, std::string>(split_vector[0], split_vector[1]) );
return "this function is okay";
}
It's just simple curl example to connect to a certain web site.
But from C#, I have to retrieve cookies as well as html, so I am passing StringBuilder to C++.
So, C++ can write cookie name and value to that StringBuilder.
Actually this codes work great in 64bit.
But if I change it into 32bit(in C# winform property), C++ gives me error in CPlusPlusClass::~CPlusPlusClass(void).
When I try to delete class2 which is Scraper class, it just kills my C# application, so I cannot even trace the error.
I am specious about Scraper.cpp when getting the cookie from curl CURLINFO_COOKIELIST.
And write them to char array which was referenced from C# StringBuilder.
So, I wrote down DoSomething2 function in Scraper.cpp.
Now, it works even when I am deleting class in 32bit or 64bit.
Does anyone have any idea about this problem?
By somehow it was fixed.
I don't know very much about the mechanism x86 nor x64, but it seems that the basic capacity are different.
I edited to fix the size of StringBuilder when I first start from C#.
StringBuilder _cookies = new StringBuilder();
to
StringBuilder _cookies = new StringBuilder(1024);
And now, I don't see that error again in 32bit computers.
Happy coding!!