Categories > Coding > C++ >
How Can I Make A Dll?
Posted
How Can I Make A dll that can just print.
Love And Thanks
SpaceSpiffer
https://media.discordapp.net/attachments/1013939973671624917/1027279180192292944/unknown.png
https://media.discordapp.net/attachments/1010670716062007347/1108945330847883274/image.png
Replied
just call the print function
Cancel
Post
Replied
@63568i am a dum dum and i dont know how to code
Cancel
Post
https://media.discordapp.net/attachments/1013939973671624917/1027279180192292944/unknown.png
https://media.discordapp.net/attachments/1010670716062007347/1108945330847883274/image.png
Replied
@Hiroku Something like this
int x(int x) { return(x - 0x400000 + reinterpret_cast<int>(GetModuleHandleA(0))); }
int print_addr = x(0x696969) // replace with the address for print
typedef void(__cdecl* print_DEF)(int, const char*); // create typedef for print
print_DEF r_print = reinterpret_cast<print_DEF>(print_addr);
r_print(rL, "hi im printing something"); // call print
you'll need to get the roblox lua state btw
Cancel
Post
Replied
@63568i smell deeppain here
Cancel
Post
https://cdn.discordapp.com/attachments/661621789591470090/1013919752294498314/Untitled_1366_768_px_1546_202_px_2.gif
Replied
just make it smh its so easy just to doing it
Cancel
Post
Replied
# LuaC #
r_getglobal("print");
r_pushstring("hi");
r_pcall(1, 0, 0);
Cancel
Post
Replied
Depends, do you want to do it using lua or call the actual print function?
I wrote some really nasty sample code, but commented it well.
You probably shouldn't use this as something to learn from since I myself am definitely not proud of this code,
but I decided to post it anyway, who knows it might help you.
#include <iostream>
#include <string>
#include <thread>
#include <Windows.h>
/*
this function allows us to create a functional cast,
that is allowed in template returns, rather than being forced
to use a C style cast
*/
template <class T, class T2>
T functional_cast(T2 const& value)
{
return T(value);
}
/*
this is a rebase implementation that works as normal, but does the casting
for you so there's no need to rewrite a cast 1000 times, when you can just change
the type
*/
template <typename T = std::uintptr_t>
const T rebase(const std::uintptr_t address)
{
return functional_cast<T>(address - 0x400000 + reinterpret_cast<std::uintptr_t>(GetModuleHandle(0)));
}
/*
we'll make an enum for simplicity, and also to ensure range isn't broken
you want to ensure the size is 4 bytes, since that's what roblox's print
function expects to input and clean, which is why we do `std::uint32_t`,
it tells the compiler to implicitly cast any of the enum values to
an unsigned int
*/
enum class output : std::uint32_t
{
print,
inform,
warn,
error
};
/*
the `using` keyword is perferred over typedef's in modern C++,
they yield the same result but using is more adaptable and easier to use
rather than writing a typedef using C standard,
the ... specifies the optional variadic args that print uses for formatting,
allowing you to call it with any number of arguments as long as its
>= 2
*/
using print_t = int(__cdecl*)(output, const char*, ...);
const auto print = rebase<print_t>(0x00674960); /* you can find this address by searching for "Current identity is" then going to the function called afterwards */
/*
rather than being a pain and using something
like magic_enum, it'd just be easier
to declare a list of the names
*/
constexpr const char* names[] =
{
"print",
"inform",
"warn",
"error"
};
/* helper function to check whether or not string is numeric */
const bool only_numeric(const std::string& input)
{
for (auto i : input)
if (i < '0' || i > '9') /* if input[idx] leaves ascii range of numbers, then at least 1 character is non-numeric */
return false;
return true; /* if it didn't return then it's clearly numeric */
}
/* helper function to easily set pages, without bad practice */
template <class T>
const std::uint32_t set_page(const T ptr, const size_t sz, const std::uint32_t page)
{
DWORD old{};
VirtualProtect(functional_cast<LPVOID>(ptr), sz, page, &old);
return old;
}
void main_thread()
{
reentry:
std::string type_s{}; /* declare a string-based container for our type */
output out_type{}; /* declare the container for the output type */
std::cout << "Enter a type: "; /* tell the user to input a type */
std::getline(std::cin, type_s); /* std::getline allows us to push to the input stream without breaking on whitespace, only newlines */
if (only_numeric(type_s))
{
const int n = std::stoi(type_s);
out_type = ((n >= 0 && n <= 3) ? static_cast<output>(n) : output::print);
}
else
{
/* should always evaluate to 4 */
for (auto i = 0; i < sizeof(names) / sizeof(const char*); i++) [[likely]]
{
if (type_s == names[i])
{
out_type = static_cast<output>(i);
goto check_end;
}
}
std::cout << "Invalid input \"" << type_s << "\"" << std::endl;
goto reentry;
}
check_end:
/* previous checks succeeded, equivalent to while (true) */
for (;;)
{
std::string input_s{};
std::cout << "> ";
std::getline(std::cin, input_s); /* accept input now */
print(out_type, input_s.c_str()); /* print using input given */
}
}
BOOL APIENTRY DllMain(HMODULE mod, DWORD type, LPVOID)
{
if (type == DLL_PROCESS_ATTACH)
{
FILE* stream;
const auto original_page = set_page(&FreeConsole, 1, PAGE_EXECUTE_READWRITE); /* allows us to write to the first byte of FreeConsole's function */
*reinterpret_cast<std::uint8_t*>(&FreeConsole) = 0xC3; /* writes a return at the start of the function */
set_page(&FreeConsole, 1, original_page); /* set the original page back */
AllocConsole(); /* create our console window */
freopen_s(&stream, "CONOUT$", "w", stdout); /* open input stream for console output */
freopen_s(&stream, "CONIN$", "r", stdin); /* open input stream for console input */
std::thread(main_thread).detach(); /* create a thread for our main function, and kill the handle we aren't using it */
}
return TRUE; /* send success back to caller */
}
Cancel
Post
Replied
https://wearedevs.net/forum/t/20695
Cancel
Post
back lol
Users viewing this thread:
( Members: 0, Guests: 1, Total: 1 )
Cancel
Post