// this is where we are intercepting all file accesses! static int InterceptDNS_Hooked( [In] string nodename, [In] string servicename, [In] ref AddressInfoW hints, [Out] out IntPtr ptrResults ) { int result_status = 0; try { Main This = (Main)HookRuntimeInfo.Callback; lock (Queue1) { Queue1.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" + RemoteHooking.GetCurrentThreadId() + "]: \"" + nodename + "\""); } } catch { } // call original API or our custom DNS lookup if (nodename != "") { // LogMessage("InterceptDNS_Hooked: nodename: " + nodename + "."); // UseCustomDNSForDomain is "all" or a domain like ".abc" with a leading dot. // App settings aren't seen here, so hardwired: string UseCustomDNSForDomain = ".altnet"; if (UseCustomDNSForDomain.Equals("all")) { result_status = AltNetGetAddrInfoW( nodename, servicename, ref hints, out ptrResults); return(result_status); } else if (nodename.IndexOf(UseCustomDNSForDomain) == nodename.Length - UseCustomDNSForDomain.Length) { // LogMessage("===START ALTNET DOMAIN LOOKUP=================="); LogMessage(nodename + " will use custom DNS lookup."); // .altnet domain, do our own lookup. // The results crash Firefox, but not if set to IntPtr.Zero ... result_status = AltNetGetAddrInfoW( nodename, servicename, ref hints, out ptrResults); return(result_status); } else { result_status = GetAddrInfoW( nodename, servicename, ref hints, out ptrResults); return(result_status); } } else { LogMessage("InterceptDNS_Hooked: nodename is empty."); result_status = GetAddrInfoW( nodename, servicename, ref hints, out ptrResults); return(result_status); } }
// ===================== static unsafe int AltNetGetAddrInfoW( [In] string nodename, [In] string servicename, [In] ref AddressInfoW hints, [Out] out IntPtr ptrResults) { string gotTo = "Start"; try { LogMessage("AltNetGetAddrInfoW(): Start."); ////// AddressInfo AltNetOut = new AddressInfo(); char *canonname = stackalloc char[100]; for (int i = 0; i < nodename.Length; i++) { canonname[i] = nodename[i]; } canonname[nodename.Length] = '\0'; // LogMessage("=== NS LOOKUP =================="); // DnsQuery_W needs to use port 53, so forward post 53 to 53534 on Raspberry Pi. string AltNetHost = "sherpoint.mooo.com"; string AltNetLocalServerAddress = "192.168.1.65"; int size = 0; // Check last name server IP update in AltNetNameServerLastCheck DateTimeNow = DateTime.Now; DateTimeMinusFiveMinutes = DateTime.Now.AddMinutes(-5); DateTimeMinusOneMinute = DateTime.Now.AddMinutes(-1); bool NeedToCheckNameserverIP = false; int LastNameServerIPResult = DateTime.Compare(AltNetNameServerLastCheck, DateTimeMinusFiveMinutes); if (AltNetNameServerIP == "0.0.0.0") { // Last check failed. // Need to fetch AltNet name server address. // If at least 1 minute has elapsed since last fetch. LastNameServerIPResult = DateTime.Compare(AltNetNameServerLastCheck, DateTimeMinusOneMinute); if (LastNameServerIPResult > 0) { // Last check was less than one minute ago. AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; NeedToCheckNameserverIP = false; AltNetResult = WSAEWOULDBLOCK; return(AltNetResult); } else { NeedToCheckNameserverIP = true; // LogMessage("Last AltNet name server IP update failed. Need to update again."); } } else { if (LastNameServerIPResult < 0) { // Last check was more than five minutes ago. // Need to fetch AltNet name server address. NeedToCheckNameserverIP = true; // LogMessage("Last AltNet name server IP update > 5 minutes ago. Need to update again."); } else if (LastNameServerIPResult == 0) { // Last check was five minutes ago. // Need to use cached name server address (if it succeeded). NeedToCheckNameserverIP = false; // LogMessage("Last AltNet name server IP update = 5 minutes ago. Need to update again."); } else if (LastNameServerIPResult > 0) { // Last check was less than five minutes ago. // Need to use cached name server address (if it succeeded). NeedToCheckNameserverIP = false; } } if (NeedToCheckNameserverIP == true) { // OK, fetch a new NeedToCheckNameserverIP. AltNetNameServerLastCheck = DateTimeNow; if (AltNetHost == null) { LogMessage("AltNet host is null: aborting name server IP lookup."); AltNetNameServerIPResult = "1.1.1.1"; } else if (AltNetHost == "") { LogMessage("AltNet host is empty: aborting name server IP lookup."); AltNetNameServerIPResult = "1.1.1.1"; } else { string AltNetNameServerIPResult = GetAltNetNameServerIPAddress(AltNetHost); if (AltNetNameServerIPResult == "0.0.0.0") { AltNetNameServerIP = AltNetNameServerIPResult; LogMessage("AltNet name server IP lookup failed (0.0.0.0 returned)."); } else if (AltNetNameServerIPResult.IndexOf("Error") >= 0) { LogMessage(AltNetNameServerIPResult); AltNetNameServerIPResult = "1.1.1.1"; AltNetNameServerIP = AltNetNameServerIPResult; } else { // Success. AltNetNameServerIP = AltNetNameServerIPResult; // LogMessage("AltNet name server IP success: " + AltNetNameServerIP); } } } if (AltNetNameServerIP == "0.0.0.0" | AltNetNameServerIP == "1.1.1.1") { LogMessage("AltNetGetAddrInfoW: IP: 0.0.0.0."); AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAEWOULDBLOCK; return(AltNetResult); } if (NeedToCheckNameserverIP == true) { LogMessage("Real AltNet name server IP is " + AltNetNameServerIP); LocalMachine = IsLocalMachine(); if (LocalMachine == true) { AltNetNameServerIPResult = AltNetLocalServerAddress; AltNetNameServerIP = AltNetNameServerIPResult; LogMessage("Running on local LAN, using " + AltNetNameServerIP + " as AltNet NS."); } } // OK, now lookup IP of .altnet host, as requested. // LogMessage("=== IP LOOKUP =================="); AltNetNameServerIPResult = LookupIPAddressUsingAltNetNS(nodename, AltNetNameServerIP); if (AltNetNameServerIPResult.IndexOf("Error") >= 0) { if (AltNetNameServerIPResult.IndexOf("DNS name does not exist") > 0) { LogMessage("AltNet NS returned NxDomain (" + nodename + " does not exist)."); AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAHOST_NOT_FOUND; return(AltNetResult); } else { LogMessage("Error looking up .altnet host: " + AltNetNameServerIPResult); } } if (AltNetNameServerIPResult == "Error: FORMATERROR") { AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAEINVAL; return(AltNetResult); } else if (AltNetNameServerIPResult == "Error: NOTIMPLEMENTED") { AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSATYPE_NOT_FOUND; return(AltNetResult); } else if (AltNetNameServerIPResult == "Error: NOTAUTHORATIVE") { AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAHOST_NOT_FOUND; return(AltNetResult); } else if (AltNetNameServerIPResult == "Error: NXDOMAIN") { AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAHOST_NOT_FOUND; return(AltNetResult); } else if (AltNetNameServerIPResult == "Error: SERVERFAILURE") { AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAEWOULDBLOCK; return(AltNetResult); } else if (AltNetNameServerIPResult == "0.0.0.0" | AltNetNameServerIPResult == "1.1.1.1") { LogMessage("AltNet domain IP lookup failed (0.0.0.0 returned)."); AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAHOST_NOT_FOUND; return(AltNetResult); } else if (AltNetNameServerIPResult.IndexOf("Error") >= 0) { LogMessage("AltNetGetAddrInfoW, catch all other errors. Returning DNS ServerError. IP: '" + AltNetNameServerIP + "'."); AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSAEWOULDBLOCK; return(AltNetResult); } // OK, success. size = 0; if (address_in_pointer != IntPtr.Zero) { // Marshal.FreeHGlobal(address_in_pointer); } // AltNetOut = new AddressInfo(); if (AltNetNameServerIPResult.IndexOf(":") >= 0) { LogMessage("DNS server returned an IPv6 address."); // hints_family = AF_INET6; } if (AltNetNameServerIPResult.IndexOf(".") >= 0) { LogMessage("DNS server returned an IPv4 address."); } else { LogMessage("DNS server failed to return an IPv4 or IPv6 address."); AltNetNameServerIPResult = "1.1.1.1"; ptrResults = IntPtr.Zero; AltNetResult = WSATYPE_NOT_FOUND; return(AltNetResult); } gotTo = "Near end"; AddressInfoW AltNetOut = new AddressInfoW(); AltNetOut.ai_canonname = canonname; AltNetOut.ai_family = AF_INET; AltNetOut.ai_flags = AddressInfoHints.AI_CANONNAME; AltNetOut.ai_protocol = IPPROTO_TCP; AltNetOut.ai_socktype = SOCK_STREAM; address_in_pointer = CreateSockaddrInStructure(AltNetNameServerIPResult, out size); AltNetOut.ai_addr = (byte *)address_in_pointer; AltNetOut.ai_addrlen = (uint)size; AltNetOut.ai_next = null; LogMessage("AltNetGetAddrInfoW: Marshalling results."); ptrResults = Marshal.AllocHGlobal(Marshal.SizeOf(AltNetOut)); Marshal.StructureToPtr(AltNetOut, ptrResults, false); // Firefox doesn't crash if we use the standard GetAddrInfoW() // or if we set ptrResults to IntPtr.Zero: // ptrResults = IntPtr.Zero; LogMessage("AltNetGetAddrInfoW: Returning successful response."); AltNetResult = 0; return(AltNetResult); } catch (Exception ex) { // Not sure how to assign ptrResults, so maybe let GetAddrInfoW() do that // and return the correct data for an error? LogMessage("Error in AltNetGetAddrInfoW(): " + ex.Message + " (" + gotTo + ")."); return(GetAddrInfoW( nodename, servicename, ref hints, out ptrResults)); } }
static extern int GetAddrInfoW( [In][MarshalAs(UnmanagedType.LPWStr)] string nodename, [In][MarshalAs(UnmanagedType.LPWStr)] string servicename, [In] ref AddressInfoW hints, out IntPtr ptrResults );