I've got this dll (called unknown.dll) from which i only know what Ghidra told me. I'm using LoadLibraryW to load it, but (in x86) it throws me the error 126. However, in 64x it gives me the error 193, so i don't think that the problem is that my program can't find my dll...
Here is my code :
#include <iostream>
#include <Windows.h>
typedef int(__cdecl* FunctionIWant)();
int main()
{
HMODULE hmod = LoadLibraryW(L"C:\\unknown.dll");
if (hmod != NULL)
{
...
}
else
std::cout << GetLastError();
return 0;
}
What am I doing wrong ?
126 is ERROR_MOD_NOT_FOUND. Either your DLL can't be found, or more likely one if it's dependencies can't be found.
193 is ERROR_BAD_EXE_FORMAT. This is because you can't mix 32 and 64 bit DLLs.
The fact that you get ERROR_BAD_EXE_FORMAT when you run under 64 bit tells you that your DLL is found. Therefore we can conclude that its dependencies are not present.
Consult the documentation to discover what dependencies are required.
Related
I have a program using cpprestsdk for http querying and websocketpp for subscribing a data stream. The program will crash immediately(it says Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)). But if I comment either of the http querying or subcribing data stream, the program won't crash.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include "json.hpp"
#include <iostream>
#include <ctime>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <vector>
#include <string>
using std::string;
using namespace web;
using std::cout, std::endl;
using std::vector;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_stream_data(websocketpp::connection_hdl hdl, message_ptr msg) {
}
class OrderBook {
public:
void initialize() {
web::http::client::http_client_config cfg;
std::string uri = string("https://fapi.binance.com/fapi/v1/depth?symbol=btcusdt&limit=1000");
web::http::client::http_client client(U(uri), cfg);
web::http::http_request request(web::http::methods::GET);
request.headers().add("Content-Type", "application/x-www-form-urlencoded");
web::http::http_response response = client.request(request).get();
}
int start_stream() {
client c;
std::string uri = string("wss://fstream.binance.com/ws/btcusdt#depth#100ms");
try {
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.init_asio();
c.set_message_handler(bind(on_stream_data, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
};
int main(int argc, char *argv[]) {
OrderBook ob;
ob.initialize(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
std::this_thread::sleep_for(std::chrono::milliseconds(10000000));
ob.start_stream(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
}
When I run this program in Clion debug mode, Clion show that the crash comes from function in /opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/ssl/detail/impl/engine.ipp
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
It says Exception: EXC_BAD_ACCESS (code=1, address=0xf000000000)
What's wrong with it? is it because I run two pieces of code using boost::asio, and something shouldn't be initialized twice?
I can compile this and run it fine.
My best bet is that you might be mixing versions, particularly boost versions. A common mode of failure is caused when ODR violations lead to Undefined Behaviour.
Note that these header-only libraries depend on a number of boost libraries that are not header-only (e.g. Boost System, Thread and/or Chrono). You need to compile against the same version as the libraries you link.
If you use distribution packaged versions of any library (cpprestsdk, websocketpp or whatever json library that is you're using) then you'd be safest also using the distribution packaged version of Boost.
I'd personally simplify the situation by just using Boost (Beast for HTTP/websocket, Json for, you guessed it).
Running it all on a test Ubuntu 18.04 the OS Boost 1.65 version, the start_stream sequence triggers this informative error:
[2022-05-22 13:42:11] [fatal] Required tls_init handler not present.
could not create connection because: Connection creation attempt failed
While being UBSAN/ASAN clean. Perhaps that error helps you, once you figure out the configuration problems that made your program crash.
I am currently building an Executable handling application in Objective C and I just wanna know a simple code that can determine if an executable file can be launched (without launching it) or if it is just a loadable one.
Thanks.
Once you've taken care of permission bits and whether the file is a Mach-O, there are three things you need to consider:
File type
CPU compatibility
Fat binaries
File type
Whether your Mach-O is an executable, dylib, kext, etc., can be determined from a field in its header.
From <mach-o/loader.h>:
struct mach_header {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype; // <---
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};
Also from <mach-o/loader.h> you get all possible values for that field:
#define MH_OBJECT 0x1 /* relocatable object file */
#define MH_EXECUTE 0x2 /* demand paged executable file */
#define MH_FVMLIB 0x3 /* fixed VM shared library file */
#define MH_CORE 0x4 /* core file */
#define MH_PRELOAD 0x5 /* preloaded executable file */
#define MH_DYLIB 0x6 /* dynamically bound shared library */
#define MH_DYLINKER 0x7 /* dynamic link editor */
#define MH_BUNDLE 0x8 /* dynamically bound bundle file */
#define MH_DYLIB_STUB 0x9 /* shared library stub for static linking only, no section contents */
#define MH_DSYM 0xa /* companion file with only debug sections */
#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */
CPU compatibility
Just because it says "executable", doesn't mean it can be launched though. If you take an iOS app and try to execute it on your iMac, you'll get a "Bad CPU type in executable" error message.
The different CPU types are defined in <mach/machine.h>, but the only of comparing against the current CPU type is via defines:
#include <mach/machine.h>
bool is_cpu_compatible(cpu_type_t cputype)
{
return
#ifdef __i386__
cputype == CPU_TYPE_X86
#endif
#ifdef __x86_64__
cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64
#endif
#ifdef __arm__
cputype == CPU_TYPE_ARM
#endif
#if defined(__arm64__)
cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64
#endif
;
}
(This will only work if your application has 64-bit slices, so that it always runs as 64-bit when it can. If you want to be able to run as a 32-bit binary and detect whether a 64-bit binary could be run, you'd have to use sysctl on "hw.cpu64bit_capable" together with defined, but then it gets even uglier.)
Fat binaries
Lastly, your binaries could be enclosed in fat headers. If so, you'll simply need to iterate over all slices, find the one corresponding to your current architecture, and check the two conditions above for that.
Implementation
There is no Objective-C API for this that I know of, so you'll have to fall back to C.
Given a pointer to the file's contents and the is_cpu_compatible function from above, you could do it like this:
#include <stdbool.h>
#include <stddef.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
bool macho_is_executable(char *file)
{
struct fat_header *fat = (struct fat_header*)file;
// Fat file
if(fat->magic == FAT_CIGAM) // big endian magic
{
struct fat_arch *arch = (struct fat_arch*)(fat + 1);
for(size_t i = 0; i < fat->nfat_arch; ++i)
{
if(is_cpu_compatible(arch->cputype))
{
return macho_is_executable(&file[arch->offset]);
}
}
// File is not for this architecture
return false;
}
// Thin file
struct mach_header *hdr32 = (struct mach_header*)file;
struct mach_header_64 *hdr64 = (struct mach_header_64*)file;
if(hdr32->magic == MH_MAGIC) // little endian magic
{
return hdr32->filetype == MH_EXECUTE && is_cpu_compatible(hdr32->cputype);
}
else if(hdr64->magic == MH_MAGIC_64)
{
return hdr64->filetype == MH_EXECUTE && is_cpu_compatible(hdr64->cputype);
}
// Not a Mach-O
return false;
}
Note that these are still rather basic checks though, which will e.g. not detect corrupt Mach-O's, and which could easily be fooled by malicious files. If you wanted that, you would have to either emulate an operating system and launch the binary within, or get into the research field of theoretical IT and revolutionize the mathematics of provability.
My understanding is you want to distinguish a Mach-O standalone executable from a Mach-O dyld library. A standalone executable will use either:
LC_MAIN load command to denote the entry point, supported since MacOS 10.7
LC_UNIXTHREAD load command , older non-dyld approach to do the same (still supported)
A dyld library will not have either of these Mach-O load commands, so if you detect one of them it means it's a runnable standalone executable. That of course does not imply the binary executable is valid and kernel won't kill it for other reasons.
If you want inspect some test files to verify it I recommend using a free tool called MachOView
Because of ASLR(Address space layout randomization, since Windows Vista), the base address of an exe is random, so it can't be found in PE file anymore.
In Visual C++ now the /DYNAMICBASE option is default enabled, so the base address
of an exe is random - everytime the loader loads it, it happens.
After did some research on google, I am trying to use this pattern,
But it doesn't work.
Please have a look at this simple code sample:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
int main()
{
STARTUPINFOA startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInformation = {0};
if (CreateProcessA("UseCase01.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))
{
std::vector<HMODULE> buf(128);
DWORD needed = 0;
for (;;) {
if (EnumProcessModulesEx(processInformation.hProcess, &buf[0], DWORD(buf.size()*sizeof(HMODULE)), &needed, LIST_MODULES_ALL) == FALSE) {
DWORD ec = GetLastError();
std::cout << ec << std::endl;
break;
}
else if (needed <= buf.size() * sizeof(HMODULE)) {
break;
}
else {
const size_t oldSize = buf.size();
buf.resize(oldSize * 2);
}
}
ResumeThread(processInformation.hThread);
}
}
My OS is Windows 7 64bit pro, my compiler is VS2013, this is a 32bit console program, and the UseCase01.exe is also a 32bit console program too.
EnumProcessModulesEx always fails, the error code returned by GetLastError() is 299, MSDN says what about this error code: ERROR_PARTIAL_COPY, "Only part of a ReadProcessMemory or WriteProcessMemory request was completed."
About this error code, on the EnumProcessModules's page of MSDN, "If this function is called from a 32-bit application running on WOW64, it can only enumerate the modules of a 32-bit process. If the process is a 64-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299)."
But I am sure my program is 32bit, And, I tested on 64bit program, it fails with error 299 too, so it doesn't make sence.
"The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object." - from MSDN, so it can't be a access rights problem ?
Then I try to use CreateToolhelp32Snapshot, it fails with error code 299 too, both 32bit and 64bit.
I just can't figure it out.
My goal is find the entry point of the sub-process in a safe way, whatever it's 32bit or 64bit process.
I found this is the "deepest" answer about this question: http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
Unfortunately, 64bit program will fails too, not only for Wow64, so it doesn't make sence.
If this is infeasible, what is the good way (find base address or entry point of a suspended sub-process)?
You are creating the process suspended. While the key kernel data structures will be created, no modules will be loaded (that would involve executing code in module entry points (dllmain)).
Thus the error makes sense: the data structures to track modules loaded will be empty, and quite possibly not allocated at all.
Put some wait it will help you it looks currently resource is not available.
On all Windows operating systems (32/64bit):
DWORD ImageBaseAddress = ((LPDWORD)PEB)[2]
I am going to design a program using WinDivert to manipulate the network traffic.
The language I use is C++ and the program is designed under Visual Studio 2008.
Firstly I create a project in visual C++ CLR (Windows Forms Application) so I can implement the UI simply.
For importing the WinDirvert Library, I have done the following setting in project properties:
Configuaration Properties: General
Common Language Runtime support: Common Language Runtime Support(/ctr)
Configuaration Properties: Linker
Additional Dependencies: link of WinDivert.lib
Module Definition File: link of windivert.def
Within the project I have created, I also added the windivert.h in the header files.
Also, windivert.h is included in the main entry point of my project (ProjectG.cpp):
#include "stdafx.h"
#include "Form1.h"
#pragma managed(push, off)
#include "windivert.h"
#pragma managed(pop)
using namespace ProjectG;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
HANDLE handle;
unsigned char packet[8192];
UINT packet_len;
WINDIVERT_ADDRESS addr;
handle = WinDivertOpen("udp", WINDIVERT_LAYER_NETWORK, 0,
WINDIVERT_FLAG_DROP);
if (handle == INVALID_HANDLE_VALUE)
{
Application::Exit();
}
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
MessageBox::Show("Fail");
continue;
}
}
return 0;
}
Finally, I put the {WinDivert.dll, windivert.h, WinDivert.lib, WinDivert32.sys} under the project directory.
However, the following error is shown:
fatal error LNK1306: DLL entry point "int __clrcall main(cli::array<class
System::String ^ >^)" (?main##$$HYMHP$01AP$AAVString#System###Z) cannot be managed;
compile to native ProjectG.obj ProjectG
Additional: (a warning)
warning LNK4070: /OUT:WinDivert.dll directive in .EXP differs from output filename
'C:\Users\David\Desktop\css\ProjectG\Debug\ProjectG.exe'; ignoring directive
ProjectG.exp ProjectG
Question:
How can I resolve this situation?
a) your main source is .cpp, so you can delete [STAThreadAttribute] and change
int main(array<System::String ^> ^args) to int _tmain(int argc, _TCHAR* argv[])
b) exclude windivert.def from linker Module Definition File, this only when you are creating a DLL
c) the DLL/SYS files would need to be copied to the Debug and Release folders
I have created a GUI using tcl. I want to make some of the core functionalities of the tcl code available to be used by any program which supports dll. For that i have taken a very simple tcl code example, which adds two integer numbers and i have written a c wrapper function to use this functionality. This is working for me. Now how can i create a dll for these two c and tcl files, so that any program can use this addition functionality by simply loading the dll.
Here is my simple tcl code :
/* Filename : simple_addition.tcl */
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
And here is my c wrapper function which uses the above tcl addition functionality :
#include <tcl.h>
#include <tclDecls.h>
#include <tclPlatDecls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
printf("inside main function \n");
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
This c wrapper is working fine for me and gives correct results.
Now I want to create a dll file, so that if i include that dll to any program that supports dll, it should be able to use this addition functionality of the above tcl code. Can anybody please tell me the way i can do it. Please help me. I am new to this dll concept.
In order to create the .dll you'll have to use something like Visual Studio and C or C++ to create the .dll (there are lots of other tools out there that can create .dll files but VS is easy to get hold of and to use.) So in VS create a new project, this needs to be a C++ WIN32 project. Select the DLL application type and the Export Symbols additional option.
VS will create a basic .dll that you can then amend to do what you want. I short I'd look at putting the creating/destruction of the intrepter into the dllmain:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
Tcl_DeleteInterp(interp);
break;
}
}
return TRUE;
}
and then create functions exported by the .dll that make use of the interpreter. If you aren't familiar with the concept of shared libaries then I'd suggest spending a little time reading up on them, try here and here for some background reading.