I am developing on a Windows Server 2008 box, with Visual Studio 2010 Ultimate, SP1. Unfortunately, the function InterlockedPushListSList is causing errors because it is undefined in my copy of WinBase.h.
Declaring the function myself does not work; linker errors occur. It looks like this function is not defined in the windows libraries for my compiler. But the documentation linked to above states that it is available for my operating system.
Some Googling has revealed that the API has been around since the development of Windows Longhorn, albeit from a non-official source, so there shouldn't be any reason for it to be missing from my point of view.
Does this function actually exist? If so, where can I get it?
I was able to reproduce your problem with MSVC 2010 and Windows SDK v7.0A. InterlockedPushListSList is not present in WinBase.h. When declaring it, I first also got a linking error... until I realized I forgot the extern "C" :-). Maybe you also forgot that? I could compile and link if I declared
extern "C"
PSLIST_ENTRY FASTCALL InterlockedPushListSList(
_Inout_ PSLIST_HEADER ListHead,
_Inout_ PSLIST_ENTRY List,
_Inout_ PSLIST_ENTRY ListEnd,
_In_ ULONG Count
);
Related
While I was compiling this project https://github.com/namazso/hdd_serial_spoofer
I got the error message above ,how can I solve this ?
I'm using vs 2017 and wdk 10 .
(Must compile in release ,debug mode is not supported .There is no DriverEntry function in this project ,the EntryPoint(void* ntoskrn, void* image, void* alloc) function in hwid.cpp is the real entry point .)
I did a lot of research but still failed to get it work .I'm a noob in kernel mode driver development .
The project uses (an apparently ignored) option
<EntryPointSymbol> to define EntryPoint as the entry.
This is documented here, but current documentation appears to mean this is really only for .exe and .dll projects.
The form of the mesage called from the Windows driver system
NTSTATUS DriverInitialize(
_DRIVER_OBJECT *DriverObject,
PUNICODE_STRING RegistryPath
)
Is incompatible with the EntryPoint in the project
EntryPoint(void* ntoskrn, void* image, void* alloc)
This is not so bad, as none of the parameters which are called for EntryPoint are used.
So the simplest implementation would be
extern "C"
{
DRIVER_INITIALIZE DriverEntry;
_Use_decl_annotations_
NTSTATUS
DriverEntry(
struct _DRIVER_OBJECT *DriverObject,
PUNICODE_STRING RegistryPath
)
{
EntryPoint(NULL, NULL, NULL);
return STATUS_SUCCESS;
}
}
Kernel development is not for the faint hearted, and running invalid kernel code on your computer could make it difficult to boot, or in extream cases damage the computer. I did not review any of the code in the project for correctness.
Please run the code in a virtual machine (vmware, virtualbox, hyper-v) to limit the damage it could do
This is not a normal driver, the kind that WDF directly supports. It is a "driverless driver", it uses an undocumented hack that is appealing to the kind of programmers that write rootkits for fun and profit. The DriverEntry() function is not actually the entrypoint for a driver, it is callback. Much like the WinMain() function is not actually the entrypoint for a native Win32 program. The EntryPoint() function in the project's source code is the replacement for the native driver entrypoint. Beware that the project appears to have rootkitty-like behavior, designed to fool a simplistic copy-protection scheme that checks a drive serial number.
The GsDriverEntry() function is the real entrypoint in a normal KMDF driver. It performs essential initialization to support the /GS compiler option, designed to detect buffer overflow. After that's done it calls DriverEntry(). The project replaces this entrypoint with EntryPoint().
This project was written with an old version of the Visual Studio project template. Several changes are necessary to get it to build properly:
C/C++ > Code Generation > Security Check. Must be "Disable security check (/GS-)", the original project file got this right.
Same property page > Control Flow Guard. Must be set to "No" to prevent a linker error. This option adds additional security checks that cannot work and must be disabled.
C/C++ > General > SDL checks. Use the dropdown arrow to override to "inherit from parent" so the option appears blank. More security checks that needs to be disabled, suppresses a warning that sdl- is incompatible with /gs-.
Same property page > Warning level. Override to "Level3 (/W3)", suppresses warnings about function arguments not being used.
Linker > Input > Additional Dependencies. Click the dropdown arrow > Edit. Untick the "Inherit from parent" checkbox and change to $(DDK_LIB_PATH)ntoskrnl.lib. Note the $(KernelBufferOverflowLib) entry in the Inherited values listbox, resolves to bufferoverflowfastfailk.lib, that is the one that contains GsDriverEntry() and produced the linker error.
Linker > Advanced > Entry Point. Must be "EntryPoint", the original project template got that right.
After this it builds clean. I did not test the resulting hwid.sys, looks a bit too evil to expose my machine to it.
Don't use .cpp source files to write your driver. Change them to .c and it should work. That was the case for me.
I know it looks trivial, or unlikely but remember Windows Kernel code is C code and Visual Studio makes various assumptions given the file extension of your source files.
There are several causes that generate the problem. In my case, a try/except in the code, which compiles on x64, but doesn't compile on x86.
Linker Tools Error LNK2019
https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?view=msvc-170
I am writing lib files in VS that have to be imported into CVI.
Recently a linker problem occured.
It says that _allmul() is an undefined symbol.
_allmul() and freinds are implemented as calls to the CRT library functions to handle various 64bit operations.
The lib file that i write is static because i want all the code to live inside it.
Linking with VS is no problem and all unittests pass.
Linking with the CVI-IDE leaves the CVI Linkter complaining about an unresolved _allmul().
I thougth that setting the /MT switch in VS is enough to make the CRT link statically, this seems to be wrong.
Why is my assumtion wrong?
How can i link the CRT calls statically?
Edit:
Here is a short demo of a project that i can compile in VS2010 but that i can not link to in CVI
The following is compiled as a LIB project:
HEADER
void print( unsigned A, unsigned B );
CODE
#include "MyprintInterface.h"
#include <stdio.h>
void print( unsigned A, unsigned B ){
long long copyA = ( long long ) A;
long long copyB = ( long long ) B;
printf_s( " %lli * %lli = %lli ", copyA, copyB, copyA * copyB );
// copyA * copyB -> this invokes allmul
// printf_s this is a ms specific function
}
This is a little late, but maybe it will help someone else.
I had very similar experience when using the gSoap toolkit with LabWindows/CVI. The toolkit generates ANSI C bindings used in creating web service clients or servers. However it sometimes generated versions of MS functions (some deprecated) that were prototyped slightly different than those in CVI. Solving this was kind of tedious, but generally followed these steps:
1) install appropriate Microsoft SDK onto your dev box. Here is one option for Microsoft SDKs. (There are others, Google it)
2) search MSDN website for the unresolved symbol to determine what .lib/.h support it. (MSDN list of variations of sprintf, for example)
3) include any required .lib/.h files.
4) make sure msvcr80.dll or msvcr100.dll (or other as appropriate) are visible to your executable. (i.e. place either in the executable run-time directory, or in the system directory.)
In addition to this I had to bring some of the #defines from the header files supporting file write/read functions, just
for example:
#define _O_TEXT 0x4000 /* file mode is text (translated) */
#define _O_BINARY 0x8000 /* file mode is binary (untranslated) */
And: (Requires Microsoft Platform SDK be installed
c:\program files\microsoft platform sdk\include\crt (copied to project dir and included in project))
fcntl.h (definition for file mode etc., _O_BINARY)
float.h (definition for isnan etc.)
io.h (definition for setmode etc.)
Also, there is an example CVI project with source code illustrating what I have described above, (including using crt) here.
[EDIT]
Regarding COFF compatible .libs when using third party libraries with respect to LabWindows/CVI - Read the posts here.
[EDIT 2]
Once you install the Windows SDK, the headers for everything in msvcrxxx.dll will be on your system. But for finding .h dependancies of a specific API call I typically have good luck just searching for it on Google: i.e. for sprintf_s et. al., the first link returned was this. It includes notes on how to use sprintf_s including source code.
As for allmul issues, I have not run into this before, but this guy did.
Recently we did some big architectural changes (i.e. mutlithreading support) to our cloud print module. Now I have to run a PreFast check on it, but because the current edition of Visual Studio 2008 that we are using does not have integrated PreFast check support, I have to do it through Windows DDK.
I am trying to build the source with WDK, but I am getting this error.
error LNK2005: "void _cdecl operator delete(void *)" (?3#YAXPAX#Z)
already defined in libcmt.lib (delete.obj)
I believe that the linker used libcpmt.lib at a prior stage and it had the same definition for delete method. The source also has c files and cpp files mixed at different module levels. Could this be the real reason why it is using both libcmp.lib and libcpmt.lib in the first place?
Is there anyway i can fix this? I don't really need a "right" way. All i want is to build the source, so that i can run PreFast check (not really concerned about link related warnings). If it gives any PreFast warning regarding this, i can skip it for the time being.
I'm getting this linker error when compiling wxWidgets in Visual Studio 2010.
msvcrt.lib(wcrtexew.obj) : error LNK2001: unresolved external symbol _wWinMain#16
Now here's the problem. The entry point for wxWidgets is this macro:
IMPLEMENT_APP(MyApp)
Which means I don't use wWinMain() as an entry.
I've tried disabling the entry point when I compile (/NOENTRY), but no dice. Nothing seems to work because if I define wWinMain(), then wxWidgets won't start because the entry is IMPLEMENT_APP.
I only receive this error when I compile as static. If I don't compile as static I'll have to supply the DLLs: msvcp100d.dll and msvcr100d.dll on Windows Server 2008 (and maybe more DLLs on older versions of Windows that don't have the library installed).
Now I understand I am linking again the debug library, but it shouldn't matter if I link again the release because I should receive the same error (unresolved external symbol _wWinMain#16).
Any solutions?
When you link to static libraries you have to ensure that the libraries were built with the EXACT SAME parameters as you used to build the application code.
So: go through all the compiler options for the library build and the application build and ensure that they match. Also, make sure that the application build is linking to the static libraries there were built using the configuration you have matched.
It is a pain! You have to decide wether you want to deal with this problem, or the problem of installing the correct DLLs on the target machine. Either way, you have to solve configuration management problems.
In your particular problem, I see the linker is looking for _wWinMain#16 which suggests that you have build your application code with unicode switched on, but are linking to a non unicode static library.
First compile wxWidgets' Library (wxWidgets\build\msw) all with the same settings you have in your project. So I enable "/MT", "Use MFC in a Static Library", and output the projects as "Release". Same exact settings on my wxWidgets' application I coded.
Now Comment out:
IMPLEMENT_APP(MyApp)
And use this for your entry point:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
char *buf;
buf = new char[wcslen(lpCmdLine) + 1];
wcstombs(buf, lpCmdLine, wcslen(lpCmdLine) +1);
wxApp::SetInstance( new MyApp());
wxEntry(hInstance, prevInstance, buf, nShowCmd);
wxEntryCleanup();
}
Do you have
IMPLEMENT_APP(MyApp)
In a .cpp file? It is typically in the accompanying file to where IMPLEMENT_APP(MyApp) is located.
I am using wxWidgets as a static library and that is what I do to compile.
I had the same problem after I changed my project's character set to unicode. My project uses multi-threaded Debug DLL (/MDd). Above workaround worked for me, too, but I wanted to find out what was actually causing the problem and use IMPLEMENT_APP.
After I changed "Use of MFC" to "Use Standard Windows Libraries" I was able to successfully build the project.
When developing and deploying native Windows applications, I often need to install a runtime before being able to run my binary, or statically link the library with my binary. For instance, after building a "Win32 Console" project with Visual Studio 2008, attempting to run the program on a fresh Windows 7 image results in:
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Issues like this one have been brought up in other posts on StackOverflow.
How does one develop applications that don't require runtimes that aren't already on the target OS (i.e. don't require installing redistributable packages or private/shared side-by-side assemblies)? How does one avoid using msvc[mpr]90.dll and just use the Windows API in \windows\system32*.{dll,sys}?
I'm thinking along the lines of the code that comes out of the demoscene, but that's frequently not made available.
Others have already responded with respect to linking CRT statically. If you also want a small binary at the same time, then your best bet is forego CRT entirely, and use only Win32 API functions as much as possible. You'll still get some CRT code, most notably related to startup (i.e. that which calls main) and shutdown (atexit handling etc), but otherwise the linker won't link CRT functions that you do not use.
You can avoid linking CRT altogether by using /Zl compiler switch. This means that main will no longer work, however - you'll need to define WinMain (name doesn't matter, but signature must match, and it must be __stdcall), and you will have to specify the name of your WinMain-like function as an entry point via linker /entry: switch. This will save you ~30Kb of CRT code (tested on a .cpp with an empty main).
If you go the latter route, you might also have to deal with issue of compiler intrinsics. There are some functions that are nominally defined by the CRT (and declared in its headers), but which are treated specially by the compiler, so that it inserts optimized assembly instructions at the point of the call where possible - examples are memset, strlen, and a good chunk of functions in <math.h>; a complete list can be found here. Since you don't have CRT, if you need these functions, or could avoid it but prefer the intrinsic because of improved performance (hard to do better than memset, for example), then you have to declare them yourself, and use #pragma intrinsic. E.g.:
// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h>
extern "C"
{
int abs(int);
void* memset(void*, int, size_t);
}
#pragma intrinsic(abs, memset)
int __stdcall main(void*, void*, char*, int)
{
char tmp[10];
memset(tmp, abs(-123), 10);
return 0;
}
The above can be compiled with:
cl /c /Zl foo.cpp
link /entry:main foo.obj
Link the CRT statically via the /MT switch (and likewise MFC, if you're using it).
Static linking limits what you can do with DLLs somewhat, but for simple executables it works like a charm. (And if you're shipping DLLs, you can always ship private assemblies anyway.)
Use the static CRT. This doesn't create a dependency on msvc*.dll. The CRT is linked directly into your program. This doesn't create dependencies, but does increase the size of your executable.
More info on different CRT options here.
Statically link the runtime. MS Visual C++ has option /MT for that (default is /MD)
I think one way to do this is to just not use Visual Studio and instead rely on the command line SDK tools. (You can alternatively figure out how to config VS to do what you want, but that seems harder.) E.g.:
cl /c app.cpp
link app.obj ws2_32.lib