Example #1
0
        /// <inheritdoc />
        protected override bool hookTarget(bool startIfNeeded)
        {
            //1. Write Bottom.dll to hdd
            System.IO.FileStream bottomDll;
            try
            {
                bottomDll = new System.IO.FileStream(FILENAME_BOTTOM_DLL, FileMode.Create);
            }
            catch //Pokemon style - gotta catch 'em all :>
            {
                Logger.log(TLogLevel.logUser, "Error: Failed to create Bottom.dll");
                return false;
            }

            try
            {
                bottomDll.Write(BottomResources.BottomDll, 0, BottomResources.BottomDll.Length);
            }
            catch (Exception e)
            {
                Logger.log(TLogLevel.logUser, "Error: Failed to write to Bottom.dll, exception: " + e.Message);
                bottomDll.Close();
                File.Delete(FILENAME_BOTTOM_DLL);
                return false;
            }
            bottomDll.Close();

            //2. Get target's process handle
            bool needToResume = false;
            HANDLE hThreadToResume = 0;

            //get window handle
            HWND hwndTarget = FindWindowA(targetClassname, 0);//FindWindowA(0, WINDOWNAME_SKYPE);
            if (hwndTarget == 0)
            {
                //looks like the process isn't running (or the classname is wrong)
                if (startIfNeeded != true)
                {
                    Logger.log(TLogLevel.logUser, "Fatal Error: " + targetName + " appears not to be running.");
                    File.Delete(FILENAME_BOTTOM_DLL);
                    return false;
                }
                Logger.log(TLogLevel.logUser, "Info: " + targetName + " appears not to be running. Trying to start it...");

                //start process suspended
                int lastBs = targetPath.LastIndexOf("\\");
                if (lastBs == -1)
                {
                    Logger.log(TLogLevel.logUser, "Fatal Error: Could not start " + targetName + ".");
                    File.Delete(FILENAME_BOTTOM_DLL);
                    return false;
                }
                String targetDir = targetPath.Substring(0, lastBs);
                STARTUPINFO si = new STARTUPINFO();
                PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                if (CreateProcessA(targetPath, null, 0, 0, 0, CREATE_SUSPENDED, 0, targetDir, ref si, out pi) != 1)
                {
                    Logger.log(TLogLevel.logUser, "Fatal Error: Could not start " + targetName + ".");
                    File.Delete(FILENAME_BOTTOM_DLL);
                    return false;
                }

                hTarget = (uint)pi.hProcess;
                hThreadToResume = (uint)pi.hThread;
                needToResume = true;
            }
            else
            {
                //looks like the process is running
                Logger.log(TLogLevel.logUser, "Info: " + targetName + " is already running.");

                //get Skype's process id
                DWORD pidSkype = new DWORD();
                GetWindowThreadProcessId(hwndTarget, ref pidSkype);

                Logger.log(TLogLevel.logDebug, "Info: Identified process with id " + pidSkype + " as " + targetName + " process.");

                //finally get the corresponding process handle
                hTarget = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD, 0, pidSkype);
                if (hTarget == 0)
                {
                    Logger.log(TLogLevel.logDebug, "Error: Could not get Skype's process handle. Insufficient rights?");
                    File.Delete(FILENAME_BOTTOM_DLL);
                    return false;
                }
            }

            //3. Write path of Bottom.dll to Skype process
            string pathBottomDll = AppDomain.CurrentDomain.BaseDirectory + FILENAME_BOTTOM_DLL + "\0";
            Logger.log(TLogLevel.logEverything, "Info: Path of Bottom module is: " + pathBottomDll);
            LPVOID addrPath = VirtualAllocEx(hTarget, 0, (SIZE_T)(pathBottomDll.Length), MEM_COMMIT, PAGE_READWRITE);
            if (addrPath == 0)
            {
                Logger.log(TLogLevel.logDebug, "Error: Could not allocate memory in Skype process.");
                File.Delete(FILENAME_BOTTOM_DLL);
                return false;
            }
            DWORD written = new DWORD();
            if (WriteProcessMemory(hTarget, addrPath, pathBottomDll, (SIZE_T)pathBottomDll.Length, ref written) == 0)
            {
                Logger.log(TLogLevel.logDebug, "Error: Could not write path of Bottom.dll to Skype process.");
                File.Delete(FILENAME_BOTTOM_DLL);
                return false;
            }
            //4. Get address of LoadLibraryA
            HANDLE hKernel32 = GetModuleHandleA("Kernel32.dll");
            if (hKernel32 == 0)
            {
                Logger.log(TLogLevel.logDebug, "Error: Could not get handle to kernel32.dll.");
                File.Delete(FILENAME_BOTTOM_DLL);
                return false;
            }
            FARPROC addrLoadLibrary = GetProcAddress(hKernel32, "LoadLibraryA");
            if (addrLoadLibrary == 0)
            {
                Logger.log(TLogLevel.logDebug, "Error: Could not get address kernel32.LoadLibraryA.");
                File.Delete(FILENAME_BOTTOM_DLL);
                return false;
            }

            //5. Call CreateRemoteThread(PID, LoadLibraryA, pPathBottomDll)
            if (CreateRemoteThread(hTarget, 0, 0, addrLoadLibrary, addrPath, 0, 0) == 0)
            {
                Logger.log(TLogLevel.logDebug, "Error: Could not create a new thread in the skype process. Last error: " + Marshal.GetLastWin32Error().ToString());
                File.Delete(FILENAME_BOTTOM_DLL);
                return false;
            }

            //6. Clean-up
            ////too lazy for VirtualFreeEx()
            CloseHandle(hTarget);

            //7. Try to connect to COM object
            int i;
            for (i = 0; i < 100; i++)
            {
                try
                {
                    comGeneric = new BottomCOM.Generic();
                    Logger.log(TLogLevel.logUser, "Successfully attached to " + targetName + " process with id: " + comGeneric.getPid());
                    break;
                }
                catch
                {
                    System.Threading.Thread.Sleep(20 + i * 10);
                }
            }

            if (i == 100)
            {
                Logger.log(TLogLevel.logUser, "Fatal Error: Failed to attach to " + targetName + " process.");
                return false;
            }

            //connect to hook engine
            comHookEngine = new BottomCOM.HookingEngine();
            if (comHookEngine.init(workingDir) != 1)
            {
                Logger.log(TLogLevel.logUser, "Fatal Error: Could not init in-process module.");
                return false;
            }

            //8. Set-up hooks
            if (comHookEngine.hookNetworkIO() != 1)
            {
                Logger.log(TLogLevel.logUser, "Fatal Error: Could not init in-process module.");
                return false;
            }

            //9. Resume process in case it was created suspended
            if (needToResume == true)
            {
                if (ResumeThread(hThreadToResume) == -1)
                {
                    Logger.log(TLogLevel.logUser, "Fatal Error: Could not resume " + targetName + " process.");
                    return false;
                }

                //wait for characteristic class to become registered
                for (i = 0; i < 100; i++)
                {
                    if (FindWindowA(targetClassname, 0) != 0)
                    {
                        break;
                    }
                    System.Threading.Thread.Sleep(20 + i * 10);
                }
                if (i == 100)
                {
                    Logger.log(TLogLevel.logUser, "Fatal Error: " + targetName + " did not load as expected.");
                    return false;
                }
            }

            initSuccessful = true;
            return true;
        }
Example #2
0
        /// <summary>
        /// The public constructor.
        /// </summary>
        /// <param name="comGeneric">An already connected COM object of type BottomCOM.Generic.</param>
        /// <param name="comHookEngine">An already connected COM object of type BottomCOM.HookingEngine.</param>
        /// <param name="handlePartner">The handle of the communication parter.</param>
        /// <param name="userIO">An interface for communication with the user.</param>
        public SessionExternalComm(BottomCOM.Generic comGeneric, BottomCOM.HookingEngine comHookEngine, String handlePartner, IUserIO userIO)
        {
            this.comGeneric = comGeneric;
            this.comHookEngine = comHookEngine;
            this.handlePartner = handlePartner;
            this.userIO = userIO;

            this.gotSessionKey = false;
        }