Trying to write a DLL for wallhack usw - c++

I'm trying to write a DLL file that I can inject into a game. I'm pretty far but when I try to compile the code I always get the error
Error LNK2001 Unresolved external symbol "" unsigned char * __cdecl Detours :: X86 :: DetourFunction (unsigned char *, unsigned char *, enum Detours :: X86Option) "(? DetourFunction # X86 # Detours ## YAPAEPAE0W4X86Option # 2 ## Z ) ".
The detours folder I use is from here:
https://github.com/Nukem9/detours
but the Detours.h file was broken because I couldn't use uint8_t so I replaced the code in there with the code from that file:
https://github.com/Nukem9/VMWareClient/blob/master/vmware_client/detours/Detours.h
The codline where I think the problem is:
oEndScene = (EndScene)Detours::X86::DetourFunction((uint8_t*)d3d9Device[42], (uint8_t*)hkEndScene);
but for those who are interested, I can post the whole code here. Just tell me in the comments. The whole code is 256 lines long

You can't just replace function definition:
uintptr_t DetourFunction(uintptr_t Target, uintptr_t Detour, X86Option Options = X86Option::USE_JUMP);
with
uint8_t *DetourFunction(uint8_t *Target, uint8_t *Detour, X86Option Options = X86Option::USE_JUMP);
Why can't you use uint8_t? Can't you just add:
typedef unsigned char uint8_t;

Related

mfc probelm in C++

Hi I'm trying to make mfc simple project to my final assignment in oop course, but after I install the mfc
I get error of:
1. STRCPY_S
The file that have the error is read only and I can't change it. I've tried to add CRT comment and change the precomplier but no result.
error description here
the line is gives the error:
inline void __cdecl strcpy_s(
_Out_writes_z_(_S1max) char *_S1,
_In_ size_t _S1max,
_In_z_ const char *_S2)
{
ATLMFC_CRT_ERRORCHECK(::strcpy_s(_S1, _S1max, _S2));
}

How to implement the RVExtension function for an ArmA 3 DLL in Rust?

I'm trying to write a DLL extension for ArmA 3 and the game docs say:
The dll is expected to contain an entry point of a form
_RVExtension#12, with a following C signature:
void __stdcall RVExtension(char *output, int outputSize, const char *function);
A part of C++ code example is:
// ...
extern "C" {
__declspec(dllexport) void __stdcall RVExtension(
char *output,
int outputSize,
const char *function
);
};
void __stdcall RVExtension(
char *output,
int outputSize,
const char *function
) {
outputSize -= 1;
strncpy(output,function,outputSize);
}
The docs also have plenty of examples in other languages like: C#, D and even Pascal, but those don't help me much, because I don't have a good understanding their FFI =(.
I'm stuck with the following Rust code:
#[no_mangle]
pub extern "stdcall" fn RVExtension(
game_output: *mut c_char,
output_size: c_int,
game_input: *const c_char
) {
// ...
}
But ArmA refuses to call it.
Thanks to #Shepmaster's advice about Dependency Walker, I was able to discover that the problem was in the function's name mangling. I expected the function name would be transformed into _name#X, but it wasn't. RVExtension was exported literally, and ArmA wasn't able to find it by the name _RVExtension#12.
It is strange, but it seems like the compiler version may play a part. I tried ~8 different versions, and was able to make it work only with Rust nightly 1.8 (GNU ABI) 32-bit.
The working code is:
#![feature(libc)]
extern crate libc;
use libc::{strncpy, size_t};
use std::os::raw::c_char;
use std::ffi::{CString, CStr};
use std::str;
#[allow(non_snake_case)]
#[no_mangle]
/// copy the input to the output
pub extern "stdcall" fn _RVExtension(
response_ptr: *mut c_char,
response_size: size_t,
request_ptr: *const c_char,
) {
// get str from arma
let utf8_arr: &[u8] = unsafe { CStr::from_ptr(request_ptr).to_bytes() };
let request: &str = str::from_utf8(utf8_arr).unwrap();
// send str to arma
let response: *const c_char = CString::new(request).unwrap().as_ptr();
unsafe { strncpy(response_ptr, response, response_size) };
}
It is also possible to rewrite the function into:
#[export_name="_RVExtension"]
pub extern "stdcall" fn RVExtension(
Some other Rust compilers may also work with:
#[export_name="_RVExtension#12"]
pub extern "stdcall" fn RVExtension(
But, for example, nightly 1.8 (MSVC ABI) 32-bit with VS 2015 will not allow # symbol and throws an error at compilation time. The MSVC version will not add #12 by itself.
Other compilers may add #12 and the function will be exported as _RVExtension#12#12.
It's also worth mentioning that ArmA is 32-bit app, so it does not work with a 64-bit DLL.

Linking C/C++ and Fortran, unresolved external symbols

My Visual studio 2010 solution file for a typical purpose consists of one fortran project (of static library type and consists of source1.f90), one C/C++ project(of application type and contains main.cpp) and 13 C/C++ project(of static library type and contains different .cpp/.h files for different classes). My purpose is to call the some of the functions in fortran source files from one of the C/C++ static library type project, But I am not able to build the program and am getting errors.
My first attempt was to call the fortran subroutine from main.cpp. But I am getting the following error:
Error 2 error LNK2019: unresolved external symbol "void __cdecl
bar_ftn(int,char *)" (?bar_ftn##YAXHPAD#Z) referenced in function _main
G:\VS2010\uakron\sourcefiles\application\main.obj
Error 3 error LNK1120: 1 unresolved externals G:\VS2010\uakron
\build\win\debug\application_app.exe 1
source1.f90
subroutine bar_ftn ( len_input_file, input_file ) bind( c )
use, intrinsic :: iso_c_binding, only : c_int
implicit none
integer(c_int), value, intent(in) :: len_input_file
character(len=1), intent(in) :: input_file(len_input_file)
! Local declarations (copy c char array into fortran character)
character(len=len_input_file) :: infile
integer :: i
print *, "in bar_ftn"
print *, len_input_file
do i=1,len_input_file
end do
end subroutine bar_ftn
main.cpp
#include<iostream>
#include<fstream>
using namespace std;
extern void bar_ftn ( int flag_len, char* flag );
static void
DisplayUsage(char* programName);
int main(int argc, char *argv[])
{
char ctext[]="helloworld abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz";
int ctext_len=sizeof(ctext);
//Call the Fortran
bar_ftn( ctext_len, ctext );
return 0;
}
On the other side, I also called the fortran function from one of the class functions from one of the C/C++ static library projects, but I am getting the same type of error (LNK2019).
Any help would be highly appreciated.
One issue is that you're declaring bar_ftn in C++, which results in name mangling, aka the odd ?bar_ftn##YAXHPAD#Z text you see in the error message. To avoid this, you'll need to prepend extern "C" before the function declaration:
extern "C" void bar_ftn ( int flag_len, char* flag ); // note that 'extern' by itself is unnecessary

UINT32 compiler version mismatch - Linking to legacy library

I am trying to link a DLL but I am constantly running into issues with UINT32.
The library is compiled against the 4.1 version of the Visual Studio compiler. The interface for my component (which was 4.1 and I am now porting to 2012) is defined with many UINT32s in it. In VC4.1 UINT32 is not defined by the compiler and so it was typedefed to unsigned long by the programmer, but from VC6 onwards UINT32 is defined as unsigned int. This makes my life hard.
My initial reaction was to try replacing all UINT32 in the interface with unsigned long and recompiling. This works as the function signatures are the same. However an unsigned long in 2012 is 64 bits wide... not 32 bits. This is not a problem in most cases but I foresee possible problems with flag parameters and return types.
What I am wondering is if I have missed a more obvious solution for this. I thought of defining a different type
typedef OAM_UINT32 unsigned long //in the library
typedef OAM_UINT32 unsigned int // in my component
But then the problem is going to be the same as what I have already with my two definitions of UINT32... right?
Any help would be much appreciated.
The Problem
Client code
#include <oam_if.h>
....
UINT32 uuid = getSomeLocalUserId();
UINT32 dwOamRetVal = dwOamGetUserDetails( uuid ); // LINK ERROR: Symbol not found
oam_if.h
UINT32 dwOamGetUserDetails( UINT32 idOfUser );
When the library (OAM) is compiled the UINT32 value is evaluated as an unsigned long. When the client component is compiled, UINT32 is evaluated as unsigned int. The linker complains because it has a symbol defined in the OAM library for dwOamGetuserDetails which rakes and returns an unsigned long, but the client is calling a function which according to it should take an unsigned int.
So while their respective inputs are unsigned numbers both 32 bits long, the signature of the function is different and the linker complains.
The only way I can see to fix it is to define everything as unsigned long directly. However then OAM will be using a 32 bit long number but the client will be using a 64 bit number!
Sample of Linker Error
error LNK2001: unresolved external symbol "public: virtual unsigned long __thiscall Message::getCallId(void)const " (?getCallId#Message##UBEKXZ) oam.lib(OAM_SsRequest.obj)
This is actually a callback from the library to the component, so in this case it is looking for a signature that matches UINT32 as defined by the libary (unsigned long) but the component is defining an unsigned int for its callback.

Getting a compile error with ntddscsi.h

I am having a bit of trouble with the following include:
#include <ntddscsi.h>
When I compile (using NetBean 7.1 & Cygwin C++ compiler), I am told that I need to define "SCSI_PASS_THROUGH" before I can use it... in ntddscsi.h however, it is defined:
typedef struct _SCSI_PASS_THROUGH {
SHORT Length;
CHAR ScsiStatus;
CHAR PathId;
CHAR TargetId;
CHAR Lun;
CHAR CdbLength;
CHAR SenseInfoLength;
CHAR DataIn;
LONG DataTransferLength;
LONG TimeOutValue;
LONG_PTR DataBufferOffset;
LONG SenseInfoOffset;
CHAR Cdb[16];
} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
Anyone have any idea what on earth is going wrong??
This might happen if you have circular dependencies, or for example LONG_PTR is not defined anywhere.