Changing IP in C++ by using addIPAdress() - c++

Like in the title - I've been working on code in C++ that changes my IP address. The program works "alright" and shows it added new IP, however the old IP stay the same and doesn't change.
So what I have to fix in my code to get rid off of the problem
If entire script is wrong I would really appreciate an example of program which would work.
The code:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
int main()
{
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize = 0;
DWORD dwRetVal;
UINT IPAddress;
UINT IPMask;
ULONG NTEContext = 0;
ULONG NTEInstance = 0;
LPVOID lpMsgBuf;
pIPAddrTable = (MIB_IPADDRTABLE *)malloc(sizeof(MIB_IPADDRTABLE));
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
pIPAddrTable = (MIB_IPADDRTABLE *)malloc(dwSize);
}
if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) == NO_ERROR) {
printf("\tAddress: %ld\n", pIPAddrTable->table[0].dwAddr);
printf("\tMask: %ld\n", pIPAddrTable->table[0].dwMask);
}
else {
printf("Call to GetIpAddrTable failed.\n");
}
IPAddress = inet_addr("192.168.0.2");
IPMask = inet_addr("255.255.255.0");
if ((dwRetVal = AddIPAddress(IPAddress,
IPMask,
pIPAddrTable->table[0].dwIndex,
&NTEContext, &NTEInstance)) == NO_ERROR) {
printf("\tIP address added.\n");
}
else {
printf("Error adding IP address.\n");
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)& lpMsgBuf, 0, NULL)) {
printf("\tError: %s", lpMsgBuf);
}
LocalFree(lpMsgBuf);
}
system("c:\\windows\\system32\\ipconfig");
system("pause");
}
Footnote: Program was modified from an example from Microsoft https://msdn.microsoft.com/en-us/library/windows/desktop/aa365875(v=vs.85).aspx Though, it contains error which makes my VS to reach breakpoints caused by 'GlobalFree(pIPAddrTable);'
If anyone interested I'm inviting for a C++ project on GitHub

All is conformant with MSDN documentation. The page on AddIpAddress states:
The AddIPAddress function is used to add a new IPv4 address entry on a local computer. The IPv4 address added by the AddIPAddress function is not persistent...
That means that calling this function will have no effect on pre-existing network addresses and just add a temporary new one.
If you want the change the static network address, you should try to use the EnableStatic method of the Win32_NetworkAdapterConfiguration class.

Related

Error writing to Windows 10 registry with WindowsAPI/C (strange situation)

I am trying to write to my Windows 10 registry, to include a program in Startup.
At the moment I have written the following code, which is not wroking:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winnt.h>
#include <winreg.h>
int main()
{
const TCHAR* path = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
LPDWORD holdResult;
PHKEY hKey;
int lResult;
//lResult = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKey);
lResult = RegCreateKeyExA(HKEY_CURRENT_USER, "myprogram", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &holdResult);
if (lResult != ERROR_SUCCESS)
{
if (lResult == ERROR_FILE_NOT_FOUND) {
printf("Key not found.\n");
return TRUE;
}
else {
printf("Error opening key.\n");
return FALSE;
}
}
printf("Key already existed or not: %p\n", holdResult);
char* szPath = "C:\\Users\\Myname\\Documents\\coolprogram.exe";
lResult = RegSetValueExA(hKey, "program", 0, REG_SZ,(LPBYTE)szPath, sizeof(wchar_t)*(wcslen(szPath)+1));
printf("Key successfully set or not: %d\n", lResult);
RegCloseKey(hKey);
return 0;
}
The strange thing is, although the code does not write anything to the registry, I get no error message, and the program executes as successful!
This is what gets printed to the terminal when I run the code:
Key already existed or not: 0000000000000002
Key successfully set or not: 0
So, the key had already been previously created, and was succesfully set, which did not happen, there is nothing in my registry.
I believe this is a permissions problem, because for some reason I cannot alter my registry permissions manually, even after setting myself as owner, it is impossible for me to allow "Full Control" to myself.
But I expected some sort of error, such as "ACCESS DENIED: INSUFFICIENT PERMISSIONS", but I am getting a success. Strange.
You are passing the wrong key path to RegCreateKeyEx(). You are trying to write your program value to HKCU\myprogram rather than to HKCU\SOFTWARE\Microsoft\...\Run.
You are also passing invalid pointers to RegCreateKeyEx(). Its last 2 parameters expect pointers to HKEY and DWORD variables, but you are passing in pointers to HKEY* and DWORD* variables instead.
You are also passing an incorrect parameter to RegSetValueExA(), too. You are giving it an ANSI string (OK, since it is an ANSI function), but are passing in a Unicode string length that is 2x the byte size of the actual ANSI string (bad).
In fact, your code shouldn't even compile as shown.
Try this instead:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winnt.h>
#include <winreg.h>
int main()
{
const char* szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
const char* szPath = "C:\\Users\\Myname\\Documents\\coolprogram.exe";
DWORD dwDisposition;
HKEY hKey;
LSTATUS lResult;
//lResult = RegOpenKeyExA(HKEY_CURRENT_USER, szKey, 0, KEY_QUERY_VALUE, &hKey);
lResult = RegCreateKeyExA(HKEY_CURRENT_USER, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, &dwDisposition);
if (lResult != ERROR_SUCCESS)
{
printf("Error creating key: %ld\n", lResult);
return 0;
}
printf("Key already existed or not: %lu\n", dwDisposition);
lResult = RegSetValueExA(hKey, "program", 0, REG_SZ, (LPBYTE)szPath, sizeof(TCHAR)*(strlen(szPath)+1));
printf("Key successfully set or not: %ld\n", lResult);
RegCloseKey(hKey);
return 0;
}

Construct if statement on TCHAR array

I have this code which prints the computer name.
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
void _tmain(void)
{
TCHAR buffer[256] = TEXT("");
TCHAR szDescription[8][32] = { TEXT("NetBIOS"),
TEXT("DNS hostname"),
TEXT("DNS domain"),
TEXT("DNS fully-qualified"),
TEXT("Physical NetBIOS"),
TEXT("Physical DNS hostname"),
TEXT("Physical DNS domain"),
TEXT("Physical DNS fully-qualified") };
int cnf = 0;
DWORD dwSize = sizeof(buffer);
if (!GetComputerNameEx((COMPUTER_NAME_FORMAT)0, buffer, &dwSize))
{
_tprintf(TEXT("GetComputerNameEx failed (%d)\n"), GetLastError());
return;
}
else _tprintf(TEXT("%s: %s\n"), szDescription[0], buffer);
if (buffer == TEXT("DESKTOP-SURPO18")) _tprintf(TEXT("CORRECT"));
dwSize = _countof(buffer);
ZeroMemory(buffer, dwSize);
}
I just want to create or construct a simple if statement like if(buffer == text("MyComputerName")) tprint(TEXT("CORRECT")); but it's not working. Or can you suggest other simplest way of code like I posted above that work with if statement easily using a computer name? Thank you.

Error code 122 using SetupDiGetDeviceRegistryPropertyW to get the required size

I want to get the Device ID of a USB stick by using the Setup API, but first I am trying to understand some of the functions I have to use. The SetupDiGetDeviceRegistryProperty documentation says I can send NULL to the buffer and buffer size to get the required size, but I am getting the 122 error code, which means:
The data area passed to a system call is too small
Can anyone tell me what am I doing wrong?
Here is my code so far:
#include <Windows.h>
#include <wchar.h>
#include <SetupAPI.h>
#pragma comment(lib, "Setupapi.lib")
int wmain(int argc, wchar_t *arv[])
{
// SetupDiGetClassDevs
HDEVINFO hDeviceInfo;
DWORD filterDevInfo = DIGCF_ALLCLASSES;
hDeviceInfo = SetupDiGetClassDevsW(NULL, NULL, NULL, filterDevInfo);
if (hDeviceInfo != INVALID_HANDLE_VALUE)
{
// SetupDiEnumDeviceInfo
DWORD memberIndex = 0;
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(
hDeviceInfo,
memberIndex,
&devInfoData))
{
fwprintf(stderr, L"Error on enum: %u\n", GetLastError());
return 1;
}
// SetupDiGetDeviceRegistryProperty
DWORD propertyRetrieved = SPDRP_DEVICEDESC;
DWORD requiredSize;
// First call to get the required size for the buffer
if (!SetupDiGetDeviceRegistryPropertyW(
hDeviceInfo,
&devInfoData,
propertyRetrieved,
NULL,
NULL,
0,
&requiredSize))
{
fwprintf(stderr, L"Error on registry property: %u\n", GetLastError());
return 1;
}
}
else
{
wprintf(L"Error code: %u\n", GetLastError());
return 1;
}
return 0;
}

How can a program read its own image from memory via ReadProcessMemory?

I am trying to make an executable which can read itself from memory using ReadProcessMemory api of windows.
Then, I will use this to calculate the checksum of executable.
This is my code :
#define PSAPI_VERSION 1
#include <string>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
#include <Wincrypt.h>
#define BUFSIZE 1024
#define MD5LEN 16
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
#pragma comment(lib, "psapi.lib")
int main(void)
{
HWND hMyProcess = (HWND)(GetCurrentProcess());
HMODULE hModule = (HMODULE)GetModuleHandle(NULL);
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
MODULEINFO moduleInfo;
if(hModule != NULL && hMyProcess != NULL){
// if (GetModuleInformation())
GetModuleBaseName(hMyProcess, hModule, szProcessName, MAX_PATH);
printf("%s\n", szProcessName);
if (GetModuleInformation(hMyProcess, hModule, &moduleInfo, sizeof(moduleInfo))){
printf("lpBaseOfDLL : %x\n", moduleInfo.lpBaseOfDll);
printf("Entry Point : %x\n", moduleInfo.EntryPoint);
printf("SizeOfImage : %x\n", moduleInfo.SizeOfImage);
}
}
// Till here working fine, problem lies below
// read process memory
TCHAR *hexEXE;
SIZE_T *lpNumberOfBytesRead;
if(ReadProcessMemory(hMyProcess, moduleInfo.lpBaseOfDll,
hexEXE, moduleInfo.SizeOfImage, 0)){
//printf("%s\n", hexEXE);
printf("Read memory\n");
printf("%d \n",strlen(hexEXE));
}
// will be implemented later, taken from --> https://msdn.microsoft.com/en-us/library/aa382380(VS.85).aspx
DWORD dwStatus = 0;
BOOL bResult = FALSE;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
/*if (!CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT)){
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
//CloseHandle(hFile);
return dwStatus;
}
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)){
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
//CloseHandle(hFile);
CryptReleaseContext(hProv, 0);
return dwStatus;
}*/
return 0;
}
Problem :
I am not able to read the my own process's memory, it's the first time I'm using WinAPI, so perhaps I am using the function in some wrong way.
The program just hangs and it shows "Windows has encountered some problem..."
Possible Reasons of Error :
I think the handle to the process ( hMyProcess ) I'm getting earlier isn't with the required privileges ( PROCESS_VM_READ ), how do I verify it and if it isn't then how do I get the correct privileges.
TCHAR *hexEXE;
SIZE_T *lpNumberOfBytesRead;
hexEXE = malloc (moduleInfo.SizeOfImage);
if(ReadProcessMemory(hMyProcess, moduleInfo.lpBaseOfDll,
hexEXE, moduleInfo.SizeOfImage, 0)){
//printf("%s\n", hexEXE);
printf("Read memory\n");
//hexEXE is not a string. Don't use it in strlen.
//printf("%d \n",strlen(hexEXE));
print("%d \n", moduleInfo.SizeOfImage);
}
The ReadProcessMemory need a memory to store the image. So, the "hexEXE" need be assign to a memory buffer.
Sorry for the extended discussion, but I got it running by changing the code to instead of using ReadProcessMemory directly iterating over the memory through a for loop like this :
long *baseAddress = (long *)moduleInfo.lpBaseOfDll;
printf("%d %x\n",baseAddress, baseAddress);
for (int i = 0; i < moduleInfo.SizeOfImage; ++i){
long *addressToRead = baseAddress+i;
printf("%x : %x\n", addressToRead, *addressToRead);
}
Here's the output :
Further thoughts
However, I don't understand why am I not able to get it using ReadProcessMemory.

Change my dynamic IP address by c++

I've got a dynamic IP address, infact I can change it from my router page (http://192.168.1.1) clicking on release and then renew.
I could made the http request by curl to the http://192.168.1.1 page but this solve the problem only on my computers that use that router.
So I'm interested to know if is there a way to update my IP by c++ without passing through the router page (192.168.1.1).
I've tried also from command line without positive result.
The code I've tried is the following:
ipconfig /release
ipconfig /renew
I've also tried this code:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "stdafx.h"
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "iphlpapi.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
// Before calling IpReleaseAddress and IpRenewAddress we use
// GetInterfaceInfo to retrieve a handle to the adapter
void __cdecl main()
{
ULONG ulOutBufLen = 0;
DWORD dwRetVal = 0;
PIP_INTERFACE_INFO pInfo;
pInfo = (IP_INTERFACE_INFO *)MALLOC(sizeof(IP_INTERFACE_INFO));
// Make an initial call to GetInterfaceInfo to get
// the necessary size into the ulOutBufLen variable
if (GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER) {
FREE(pInfo);
pInfo = (IP_INTERFACE_INFO *)MALLOC(ulOutBufLen);
}
// Make a second call to GetInterfaceInfo to get the
// actual data we want
if ((dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen)) == NO_ERROR) {
printf("\tAdapter Name: %ws\n", pInfo->Adapter[0].Name);
printf("\tAdapter Index: %ld\n", pInfo->Adapter[0].Index);
printf("\tNum Adapters: %ld\n", pInfo->NumAdapters);
}
else if (dwRetVal == ERROR_NO_DATA) {
printf("There are no network adapters with IPv4 enabled on the local system\n");
return;
}
else {
LPVOID lpMsgBuf;
printf("GetInterfaceInfo failed.\n");
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL)) {
printf("\tError: %s", lpMsgBuf);
}
LocalFree(lpMsgBuf);
return;
}
// Call IpReleaseAddress and IpRenewAddress to release and renew
// the IP address on the first network adapter returned
// by the call to GetInterfaceInfo.
if ((dwRetVal = IpReleaseAddress(&pInfo->Adapter[0])) == NO_ERROR) {
printf("IP release succeeded.\n");
}
else {
printf("IP release failed: %ld\n", dwRetVal);
}
if ((dwRetVal = IpRenewAddress(&pInfo->Adapter[0])) == NO_ERROR) {
printf("IP renew succeeded.\n");
}
else {
printf("IP renew failed: %ld\n", dwRetVal);
}
// Free memory for IP_INTERFACE_INFO
if (pInfo != NULL) {
FREE(pInfo);
}
std::cout << ("\n Processo terminato\n");
std::system("PAUSE");
return;
}
I've DHCP Server enabled whit these values:
DHCP Service State
DHCP State: Enabled
IP iniziale DHCP: 192.168.1.2
IP finale DHCP (Riservato per uso interno): 192.168.1.254
I need run my program on windows XP and Windows 7 platform.
Thank's for your help
The IP Helper functions include IPReleaseAddress and IPRenewAddress to do exactly this.
You'll need to start by enumerating the network adapters though, and pass the correct adapter's ID to the functions to do that. You usually do that with GetInterfaceInfo.
I thounght that changin my dynamic IP I would change also my public IP. But it is not so.
To change my Public IP Addres I haven't to change the dynamic IP, but I need change the ROUTER IP.
Infact the ISP assign an ip for any router connection that will be the public IP for any devides connected.
(For public IP I mean the IP address you can see in http://www.ipmy.it/)
So if I want to change my public IP address I have to change my router IP address.
To change it I have to disconnect and reconnect my router power supply, or I can do it through the router panel (192.168.1.1).
So the only automatic solution is to write a program executing that http request.
I wrote it in c++ using libCURL.
Thank's to all for the support.