Cannot implement password filter - c++

I try to implement password filter, so I write a simple password filter.
I followed the document in the MSDN, and make sure that the functions are declared correctly.
I compile in VS 2010.
.def file:
LIBRARY myFilt
EXPORTS
InitializeChangeNotify
PasswordFilter
PasswordChangeNotify
.cpp file:
#include <windows.h>
#include <stdio.h>
#include <ntsecapi.h>
void writeToLog(const char* szString)
{
FILE* pFile = fopen("c:\\work\\logFile.txt", "a+");
if (NULL == pFile)
{
return;
}
fprintf(pFile, "%s\r\n", szString);
fclose(pFile);
return;
}
// Default DllMain implementation
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(L"DllMain");
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOLEAN __stdcall InitializeChangeNotify(void)
{
OutputDebugString(L"InitializeChangeNotify");
writeToLog("InitializeChangeNotify()");
return TRUE;
}
BOOLEAN __stdcall PasswordFilter(
PUNICODE_STRING AccountName,
PUNICODE_STRING FullName,
PUNICODE_STRING Password,
BOOLEAN SetOperation
)
{
OutputDebugString(L"PasswordFilter");
return TRUE;
}
NTSTATUS __stdcall PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING NewPassword
)
{
OutputDebugString(L"PasswordChangeNotify");
writeToLog("PasswordChangeNotify()");
return 0;
}
I put myFilt.dll in %windir%\system32, add "myFilt" to "Notification Packages" in the registry, restart the computer, change the password, and nothing happens.
I opened depends.exe and saw that the functions are correctly:
InitializeChangeNotify
PasswordChangeNotify
PasswordFilter
Where is the mistake??
Thanks.

I found the problem! I changed the runtime library from Multi-threaded Debug DLL (/MDd) to Multi-threaded Debug (/MTd) and it works perfect! :)
– user1375970 May 5 at 10:38

Notification Packages
Specifies the dynamic-link libraries (DLLs) that are loaded or called when passwords are set or changed. To specify more than one file, list the file names one above the other by pressing ENTER between each file name.
above the other!

Related

Can't call function from .dll created in C++

I'm able to call function from DLL created in C (.c file), but i can't do it from DLL created in C++ (.cpp file). I want to find out why it doesn't work in .cpp file.
I'm trying to call function printword() from a simple DLL, created with Visual Studio 2022:
// FILE: dllmain.cpp
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
__declspec(dllexport) void printword() {
std::cout << "word" << std::endl; //with printf() doesn't work too
}
And when i call function the way like this:
int main() {
HMODULE dll;
if ((dll = LoadLibrary(L"D:\\Visual Studio projects\\Dll1\\x64\\Debug\\Dll1.dll")) == NULL) {
return GetLastError();
}
FARPROC func;
if ((func = GetProcAddress(dll, "printword")) == NULL) {
return GetLastError();
}
func();
return 0;
}
GetProcAddress throws error ERROR_PROC_NOT_FOUND
But if i create DLL in file with .c suffix printword() function calls correctly (with same code above):
// FILE: dllmain.c
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
__declspec(dllexport) void printword() {
printf("word\n");
}
The exported function's name will get mangled when the DLL is compiled. You must use the mangled name in GetProcAddress() in order for it to work. For example, the mangled name
in MSVC is:
GetProcAddress(dll, "?printword##YAXXZ");
Or, you could add this to the function's body to tell the compiler not to mangle it:
__declspec(dllexport) void printword() {
#pragma comment(linker, "/EXPORT:" __FUNCTION__"=" __FUNCDNAME__)
printf("word\n");
}
Alternatively, adding extern "C" will also solve the problem.
Review and try the recommendations from this article:
https://learn.microsoft.com/sr-cyrl-rs/cpp/build/exporting-cpp-functions-for-use-in-c-language-executables?view=msvc-170
Example
// MyCFuncs.h
extern "C" __declspec( dllexport ) int MyFunc(long parm1);
Key part being extern "C"
[I accidentally posted the link for importing instead of exporting earlier - corrected for the export article]

Can't load custom DLL

I created a simple DLL that open cmd.exe.
I did it with these options:
In the default dlllmain.cpp I added a code that creates a new cmd.exe:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <Windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
BOOL h = CreateProcessW(L"C:\\Windows\\System32\\cmd.exe", L"", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
These three lines below the DLL_PROCESS_ATTACH worked for me when I tested it with a console application.
I am expecting that every process that will load this DLL will open cmd.exe.
I tried to load the DLL with PowerShell:
Add-Type -TypeDefinition #"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class Kernel32
{
[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary(
[MarshalAs(UnmanagedType.LPStr)]string lpFileName);
}
"#
$LibHandle = [Kernel32]::LoadLibrary("C:\tmp\myDll.dll")
But nothing happens, the value of the $LibHandle was 0.
What I am doing wrong ?
I found what was the problem.
My system is 64 bit and the file was compiled in 32 bit.
I needed to specify in Visual Studio that I am compiling it in x64 bit.
I didn't check it in the beginning because I thought that when I am compiling it on "Any CPU" mode, it compile the file in 64 bit automatically as the OS architecture.
Now it works fine.

Dll not being loaded in Firefox but loads in custom application

I posted a recent question on SO about code injection, this one is similar but not the same. I am injecting dll into Firefox, it injects successfully but the code in the DLL doesn't run. If i inject the same code into a custom application, it works. Why might that be. This is the code that I'm using.
Injector.exe // the file that's injecting the code
#include <stdio.h>
#include <windows.h>
#define procId 2844
#define dllname "dllinject.dll" // located in same directory
int main()
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, procId);
LPVOID allocated = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllname), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, (LPVOID)allocated, dllname, strlen(dllname), NULL);
LPVOID libaddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)libaddr, NULL, NULL);
CloseHandle(hProc);
return 0;
}
Simpleinjected.exe // the file being injected
#include <stdio.h>
int main()
{
printf("Hello");
return 0;
}
dllinject.dll
#include <windows.h>
int message(const char *msg)
{
MessageBox(NULL, msg, "Message from Dll", MB_OK);
return 0;
}
BOOL WINAPI DLLMain(HINSTANCE hInstDll, DWORD ulReason, LPVOID lpReserved)
{
switch(ulReason)
{
case DLL_PROCESS_ATTACH:
message("process attach");
break;
case DLL_THREAD_ATTACH:
message("thread attach");
break;
case DLL_PROCESS_DETACH:
message("process detach");
break;
case DLL_THREAD_DETACH:
message("thread detach");
break;
}
return true;
}
It works when injected into simpleinjected.exe but when injected in Firefox, nothing happens even though the dll is injected successfully.
I cannot reproduce your observations. I was able to inject dllinject.dll into other processes (also firefox) but I've never seen a message box.
After a bit of digging I found that your DLLMain is spelled wrong. Change it into DllMain and you'll see message boxes in Firefox.
By the way: You propably want to change MessageBox into MessageBeep since FireFox creates/destroys a lot of threads... (this is annoying even for a quick test!)

PUNICODE_STRING printed to a log

I have a password filter dll which, for now at least, is simply going to write to a log the username and the password when a user account's password is successfully changed. I'm coming up to some age-old problems with c-strings.
The two variables I'm interested in are of the type PUNICODE_STRING (which is simply a *UNICODE_STRING). Naturally I search the web for this data type which landed me here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa380518(v=vs.85).aspx
Give that information I know that I can access the length of this animal and that it has a pointer to a wide-character string. Awesome. That is plenty of knowledge to extract the contents I'll need (so I thought).
Here is my dll code (dllmain.cpp)
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <iostream>
#define LOGFILE "c:\\PasswordFilter.txt"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void WriteToLog (const wchar_t* UserName, const wchar_t* NewPassword)
{
#ifdef LOGFILE
FILE* log = fopen(LOGFILE, "a");
if(NULL == log)
{
return;
}
fwprintf(log,L"%s password was successfully reset to %s\r\n",UserName,NewPassword);
fclose(log);
#endif
return;
}
LPWSTR __stdcall ConvertWideChar(PUNICODE_STRING input)
{
wchar_t* wszString = new wchar_t[input->Length + 1];
memset(wszString, 0, sizeof(wchar_t) * (input->Length + 1));
wcsncpy(wszString,input->Buffer,input->Length);
#ifdef LOGFILE
FILE* log = fopen(LOGFILE, "a");
if(NULL != log)
{
fwprintf(log,L"value of wszString: %s\r\n",wszString);
fclose(log);
}
#endif
return wszString;
}
BOOLEAN __stdcall InitializeChangeNotify(void)
{
return TRUE;
}
NTSTATUS __stdcall PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING NewPassword
)
{
LPWSTR ConvertedUserName = ConvertWideChar(UserName);
LPWSTR ConvertedNewPassword = ConvertWideChar(NewPassword);
WriteToLog(ConvertedUserName,ConvertedNewPassword);
return 0;
}
BOOLEAN __stdcall PasswordFilter(
PUNICODE_STRING AccountName,
PUNICODE_STRING FullName,
PUNICODE_STRING Password,
BOOLEAN SetOperation
)
{
return TRUE;
}
And here is the contents of the header file (stdafx.h)
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <stdio.h>
#include <windows.h>
#include <winnt.h>
#include <NTSecAPI.h>
// TODO: reference additional headers your program requires here
Naturally my concern is to retain accuracy. And this is where my pain begins. We have a wchar_t which communicated to me that this is likely in unicode with a UTF16 format (like all other windows based strings). The code above copies the PUNICODE_STRING's buffer to a zero-terminated wchar_t (since the buffer isn't guaranteed to be zero terminated itself) and then attempts to output that string to a log file.
I first attempted to use WideCharToMultiByte as a way to copy the buffer to a character string but that never seemed to work. The result would be null each and every time. This also ran the issue of translating unicode values to a simpler format which runs the risk of data loss. So I decided to go with what I have there for now, but the logged values have ?'s and other garbage after them, which is likely a unicode problem.
I would REALLY like to retain the unicode encoding type of this data structure if possible. How can I do so and print my values to a log?
You are not using the UNICODE_STRING::Length field correctly. It is expressed in bytes, not in characters. So you are not allocating+filling your null-terminated buffers correctly. You are also leaking the buffers you allocate.
You don't need to allocate the buffers at all. You can pass the original Buffer and Length values directly to fwprintf, no null terminators needed:
NTSTATUS __stdcall PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING NewPassword
)
{
#ifdef LOGFILE
FILE* log = fopen(LOGFILE, "a");
if (NULL != log)
{
fwprintf(log, L"%.*s password was successfully reset to %.*s\r\n",
UserName->Length / sizeof(WCHAR), UserName->Buffer,
NewPassword->Length / sizeof(WCHAR), NewPassword->Buffer);
fclose(log);
}
#endif
return 0;
}
If you really need to add null terminators, use std::wstring instead of allocating+copying manually:
#include <string>
NTSTATUS __stdcall PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING NewPassword
)
{
#ifdef LOGFILE
FILE* log = fopen(LOGFILE, "a");
if (NULL != log)
{
fwprintf(log, L"%.s password was successfully reset to %.s\r\n",
std::wstring(UserName->Buffer, UserName->Length / sizeof(WCHAR)).c_str(),
std::wstring(NewPassword->Buffer, NewPassword->Length / sizeof(WCHAR)).c_str());
fclose(log);
}
#endif
return 0;
}
You can actually print a UNICODE_STRING structure using the modifier %wZ with printf. No need for any fancy Buffer translations or worrying about null terminators.
UNICODE_STRING someStr;
RtlInitUnicodeString(&someStr, L"Hello");
printf("String: %wZ\n", &someStr);
fini.

Application Crashes when hooked with MS Detours and Injected with Withdll.exe

I am hooking FindNextFile() using MS Detours. I have configured the Detours library successfully and wrote a dll named "Detuors.dll" and an application named "FNFSend.exe". The following is the code:
DLL:
#include <cstdio>
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#pragma comment (lib,"detours.lib")
//Prototypes
extern "C" __declspec(dllexport) BOOL (WINAPI *pFNF)(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) = FindNextFile;
extern "C" __declspec(dllexport) BOOL WINAPI MyFNF(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData);
//Log File
FILE* pFNFLogFile;
int counter = 0;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pFNF, MyFNF);
if(DetourTransactionCommit() == NO_ERROR)
OutputDebugString("FNF() detoured successfully");
else
OutputDebugString("FNF() not detoured");
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin(); //Detach
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)pFNF, MyFNF);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
DisableThreadLibraryCalls(hDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pFNF, MyFNF);
if(DetourTransactionCommit() == NO_ERROR)
OutputDebugString("FNF() detoured successfully");
else
OutputDebugString("FNF() not detoured");
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
//Open file, write contents, close it
extern "C" __declspec(dllexport) int WINAPI MyFNF(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
counter ++;
fopen_s(&pFNFLogFile, "C:\\FNFLog.txt", "a+");
fprintf(pFNFLogFile, "%s\n", counter);
fclose(pFNFLogFile);
return pFNF(hFindFile, lpFindFileData);
}
Both the codes compiled successfully with no errors. The application calls FindNextFile() recursively and the dll hooks it and write the counter to a file.
I then used the tool named "withdll.exe" that is provided by detours library itself to create a process with a dll injected in it. So I injected my dll into the application using command:
withdll /d:Detuors.dll "C:\FNFSend.exe"
After injection, the function is hooked successfully, i.e. the file is made in the dirctory but suddenly the application crashes. After debugging in visual studio, I saw the exception in "output.c" as follows:
Unhandled exception at 0x6265984f (msvcr90d.dll) in FNFSend.exe: 0xC0000005:
Access violation reading location 0x00000001.
Kindly help in rectifying the problem.
%s is not a valid format string for printing out a number. Use %d instead.
By specifying %s you're telling fprintf to read the memory at address counter as a string. The first value you try calling fprintf with is 1 which is why there is an access violation at address 0x00000001.