|
321
|
Programación / .NET (C#, VB.NET, ASP) / Re: [duda]Mostrar los numeros primos entre un intervalo
|
en: 12 Mayo 2011, 18:15 pm
|
Hace tiempo hice un código para factorizar y la función IsPrime la modifique hasta obtener los resultados más rápidos posibles sin algoritmo y el codigo quedo así: Explique cada línea Public Function IsPrime(ByVal n As Long) As Boolean ''Si es 1 no es primo If n = 1 Then Return False ''Si es 2 es primo ElseIf n = 2 Then Return True End If 'Si la raiz de "n" es exacta entonces no es primo If Math.Sqrt(n) Mod 2 = 0 Then Return False End If ''Desde el 2 hasta el número "n - 1" For x As Long = 2 To (n - 1) ''Si "n" divisible entre "x" ''entonces no es primo If (n Mod x) = 0 Then Return False End If Next ''Despues de todas las comprobaciones '' fallidas entonces "n" es primo Return True End Function
|
|
|
324
|
Programación / Programación C/C++ / Re: Inyección de Codigo para API Hook
|
en: 16 Abril 2011, 06:06 am
|
Lo que quiero es la primera opción inyectar el código de las funciones para hacer hook pero me tiene confundido lo de las estructuras, entiendo el principio, debo inicializar todas las variables, funciones y otras cosas y copiar en el espacio de memoria del proceso externo para que el ejecute y se hookee el mismo, lo que necesito es el primer paso para inyectar las funciones que puse en el primer post al menos un ejemplo de como se inyecta HookFuncion.
|
|
|
325
|
Programación / Programación C/C++ / Inyección de Codigo para API Hook
|
en: 16 Abril 2011, 05:42 am
|
LLevo no mucho tiempo programando en C++ estoy intentando hacer un hook por inyección de código, tengo el código que inyecta código directamente en un proceso y tengo la funciones que hacen un hook por tramplín a una función (API). Quisas este equivocado o suene ignorante XD soy nuevo con los hook y estas cosas quisiera que me corrigieran si estoy equivocado, mi pregunta es: ¿debo inyectar en el proceso externo las funciones que se encargan del hook?, quiero decir para que el proceso externo ejecute el mismo la función que hookea el API. Pero no entiendo como hacerlo llevo horas y me tiene confundido si me pudiesen hechar una mano solo darme el camino para seguir estaria agredecido. Les dejo los sources: Hook por Trampolín (Ejemplo en el mismo Proceso)#include <windows.h> #include <stdio.h> DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup); BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup); int Hooked_MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); BYTE BackUp[6]; LPCSTR Function = "MessageBoxExA"; void WinMainCRTStartup() { MessageBoxA(0, "=( Sin Hook", "", MB_OK); // Mensaje HookFunction("user32.dll", Function, Hooked_MessageBox, BackUp); // Hookear Función MessageBoxA(0, "=( Sin Hook", "", MB_OK); // Mensaje } int Hooked_MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) // Función a la que se desvia la función original { UnHookFunction("user32.dll", Function, BackUp); // Se llama a la función UnHook para evitar la recursividad int x = MessageBoxA(hWnd, "=) Hooked", lpCaption, uType); // Se llama la función original HookFunction("user32.dll", Function, Hooked_MessageBox, BackUp); // Se aplica el Hook nuevamente return x; // Se retorna el resultado de la función original } DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup) // Función que realiza el Hook al API { DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName); // Obtiene la dirección de la API // Array de opcodes en lenguaje de maquina (ASM) para desviar la función BYTE jmp[6] = { 0xe9, //jmp 0x00, 0x00, 0x00, 0x00, //address 0xc3 }; //retn ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0); // Se guardan los primeros 6 bytes de la función DWORD dwCalc = ((DWORD)lpFunction - dwAddr - 5); // ( to - from) - 5 // Se calcula la posición donde se escribira el salto memcpy(&jmp [1], &dwCalc , 4); // Se copia en memoria el salto WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 6, 0); // Se escribe en memoria los 6 bytes del salto return dwAddr; // Se retorna la dirección del API } BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup) // Función que retira el Hook de la API { DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName); // Se obtiene la dirección de la API if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0)) // Si se logra escribir los bytes guardados en la función HookFunction { return TRUE; // Se retorna TRUE } return FALSE; // Sino entonces se retorna FALSE }
Inyecta código en un proceso externo (Ejemplo hacer que un proceso externo ejecute un MessageBox)#include <windows.h> #include <tlhelp32.h> #include <stdio.h> //Creamos un puntero a la api que queremos inyectar typedef int (WINAPI *datMessageBoxA) (HWND, LPCTSTR, LPCTSTR, UINT); //La estructura que inyectaremos struct datos { datMessageBoxA apiMessageBoxA; char titulo [20]; char mensaje [20]; }; //Declaración de funciones DWORD GetAdres(char *module, char *function); //La función que inyectaremos DWORD inyectada (datos *data) { data -> apiMessageBoxA (0, data->mensaje, data->titulo, 0); return 0; } //La función inyectora void inyectora() { int pid; // Este es el pid del proceso en el que nos queremos inyectar HANDLE proc; // El handle del proceso en el que inyectaremos datos dat; // El tipo de dato de la estructura DWORD TamFun; // El tamaño de la función a inyectar void* esp; // Lugar de memoria donde copiaremos nuestra función HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //Obtenemos el pid PROCESSENTRY32 procinfo = { sizeof(PROCESSENTRY32) }; while(Process32Next(handle, &procinfo)) { if(!strcmp(procinfo. szExeFile, "APIHOOK.exe")) { CloseHandle(handle); pid = procinfo.th32ProcessID; } } CloseHandle(handle); //Abrimos el proceso en el que nos inyectaremos proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid); //Metemos la dirección de la api en la estructura llamando a la función GetAdres dat.apiMessageBoxA = (datMessageBoxA) GetAdres ("USER32.DLL", "MessageBoxA"); //Inicializamos las variables que contendrán el mensaje //Reservamos espacio para nuestra estructura en el proceso a inyectar y la escribimos datos *dat_ = (datos*) VirtualAllocEx(proc, 0, sizeof(datos), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(proc, dat_, &dat, sizeof(datos), NULL); //Calculamos el tamaño de la función a inyectar TamFun = (long unsigned int) inyectora - (long unsigned int)inyectada; //Reservamos espacio para la función, escribimos en él y creamos un hilo esp = VirtualAllocEx(proc, 0, TamFun, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(proc, esp, (void*)inyectada, TamFun, NULL); CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE) esp, dat_, 0, NULL); } //La función main int main() { inyectora(); return EXIT_SUCCESS; } //Función que nos devuelve un DWORD con la dirección de una api DWORD GetAdres(char *module, char *function) { HMODULE dh = LoadLibrary(module); DWORD pf = (DWORD)GetProcAddress(dh,function); FreeLibrary(dh); return pf; }
|
|
|
327
|
Programación / .NET (C#, VB.NET, ASP) / [Aporte] Factorización Relativamente Rápida - Actualizado 18/08/2012 -
|
en: 15 Marzo 2011, 04:38 am
|
Cada vez más rápido y con más soporte para números más grandes Quizás a alguien le sirva factoriza números enteros incluso mayores que Decimal.MaxValue en menos de una décima de segundo para la mayoría hay números que se factorizan más lento que otros pero es un un porcentaje muy bajo. La solución es exponencial en tiempo polinomial, quiere decir que todo número N que sea Natural puede ser factorizado por este algoritmo en un tiempo relativamente corto y este se va exponiendo (Aumentando) con los dígitos que contenga N. Function PSqrt(ByVal N As Decimal) As Decimal PSqrt = 1D Try Dim L As Decimal = Math.Floor(Math.Log(N)) Dim b As Decimal, c As Decimal, d As Decimal For a As Decimal = L To 2D Step -1D b = 1D / a c = Math.Floor(N ^ b) d = (c ^ a) If d = N Then Return a End If Next Catch ex As OverflowException Return 1D End Try End Function Public Primes As Decimal() = New Decimal() {2D, 3D, 5D, 7D} Public Function IsPrime(ByVal N As Decimal) As Boolean If (N Mod 2D = 0D) Then Return False End If If PSqrt(N) > 1D Then Return False End If If Primes.Contains(N) Then Return True End If IsPrime = True Dim R As Decimal = Math.Floor(Math.Sqrt(N)) For Y As Decimal = 3D To R Step 2D If (N Mod Y = 0D) And (Not Y = N) Then Return False End If Next End Function Public Function Factorize (ByVal N As Decimal ) As Dictionary(Of Decimal, Decimal ) Dim PSqrtD As Decimal = PSqrt(N) If PSqrtD > 1D Then Dim SSqrt As Decimal = N ^ (1D / PSqrtD) If IsPrime(SSqrt) Then Factorize.Add(SSqrt, PSqrtD) Else For Each x As KeyValuePair(Of Decimal, Decimal) In Factorize(SSqrt) Factorize.Add(x.Key, x.Value * PSqrtD) Next End If Else If IsPrime(N) Then Factorize.Add(N, 1D) Else While N Mod 2D = 0D N /= 2D If Factorize.ContainsKey(2D) Then Factorize.Item(2D) += 1D Else Factorize.Add(2D, 1D) End If End While If N > 1D Then Dim I As Decimal = 3D Again: Dim R As Decimal = Math.Floor(Math.Sqrt(N)) For X As Decimal = I To R Step 2D If N Mod X = 0D Then If Factorize.ContainsKey(X) Then Factorize.Item(X) += 1D Else Factorize.Add(X, 1D) End If N /= X I = X GoTo Again End If Next If N > 1D Then If Factorize.ContainsKey(N) Then Factorize.Item(N) += 1D Else Factorize.Add(N, 1D) End If End If End If End If End If End Function
Bueno, y algunos se preguntarán como es posible que factorize el número 79.228.162.514.264.337.593.543.950.335 (Decimal más grande de 96 Bits soportado) en menos de 1 segundo Este algoritmo no se enfrasca en lo que hacen los demás, realizar ese For interminable desde 0 hasta N comprobando la divisibilidad y luego la primadilidad del número divisible, tardarías millones de años literalmente en factorizar el número anterior. Sino que se basa en leyes y propiedades básicas de los primos, por ejemplo: Un N no puede tener más de un factor que supere su raíz, así que no encontraremos ningún factor que se repita 2 veces al pasar la raíz, de igual forma el primer divisible de N siempre es primo y se encuentra en el rango de 1 a raíz de N. Ejemplo:
Los factores del número 123.456.789, su raíz redondeada es 11.111, están entre 2 y 11.111 y no pueden haber factores que se repitan más grandes que dicha raíz.
Debido a que los primos forman a los compuestos, siempre estará primero un primo que un compuesto en la recta numérica ya que el compuesto siguiente al primo esta conformado por un primo anterior. Desde el 2 a todos los compuestos le antecede un primo e igualmente están compuestos por el primo que les antecedió
2, 3, 4, 5, 6, 7, 8, 9, ...
Siendo el 2, 3, 5 y 7 primos en esta recta, de manera que para el número 1.023, el primer divisible que aparece es el 3 y este es primo, Otros divisibles de 1.023 quizás sean compuestos de 3 y debido a esto es imposible que se escape un compuesto en la lista porque siempre estará primero un primo. Y así con cualquier número entero N que sea compuesto.
Al dividir el primer factor encontrado de N generará un compuesto y los factores de este serán factores de N, aplicando este procedimiento hasta que se generé un número primo, se podrán obtener todos los factores de N y cuantas veces estos se repiten. Dicho procedimiento no consume casi tiempo ya que cada vez el valor generado se va haciendo más pequeño y el primer factor se encontrará antes de la raíz así que el procedimiento se verá cortado antes de finalizar en el caso de que N sea compuesto, no es necesario comprobar los números de 2 a raíz de N, se puede disminuir el tiempo de operación a la mitad si se ignoran los números pares que son compuestos de 2 y por lo tanto no pueden ser factores de N. En el mismo caso del 1.023 el primer divisible es 3 y el resultado es 341, aplicamos el método nuevamente y el primer divisible es 11 que también es primo eso da como resultado 31 que es un primo y la operación no se puede continuar, esto arroja que los factores de 1.023 son 3, 11 y 31. Si comprobamos 3 * 11 * 31 = 1.023.
Un número N es cuadrado perfecto de indice I, cuando existe un número X en el rango [2D, Log(N)], que satisfaga la siguiente condición: N ^ (1/X) 'Es Entero' N ^ (1/X) ^ X = N
Lo que quiere decir que si N ^ (1/X) es primo, entonces N es compuesto por I factores de dicho primo. Si en cambio N ^ (1/X) es compuesto, entonces los factores de N serán I-ésimas veces los factores primos de dicho compuesto. El restante de N después de aplicar el algoritmo, de dividir N por el primer factor que se encuentre hasta que no se encuentre ningún otro, es primo.
|
|
|
329
|
Programación / .NET (C#, VB.NET, ASP) / Re: Obtener dirección y Tamaño de #strings
|
en: 13 Marzo 2011, 04:51 am
|
No se si sea la forma más facil pero así calcule el offset de #strings XD Dim fStream As New FileStream("C:\Ejemplo.exe", FileMode.Open, FileAccess.ReadWrite) Dim Table As New String(String.Empty) Do While Table <> "35126" Table = fStream.ReadByte.ToString & fStream.ReadByte.ToString Loop Dim MainTableOffset As Long = (fStream.Position - 2) Dim StringsTableOffset As Long = 0 Dim Bytes As New List(Of String) Do While fStream.Position <> MainTableOffset + 2 + 5 Dim CurrentByte As Long = fStream.ReadByte If CurrentByte <> 0 Then If CurrentByte.ToString.Length = 1 Then Bytes.Add("0" & CurrentByte.ToString("X")) Else Bytes.Add(CurrentByte.ToString("X")) End If End If Loop Bytes.Reverse() Dim Hex As New String(String.Empty) For Each y As String In Bytes Hex += y Next StringsTableOffset = CInt("&H" & Hex) + MainTableOffset - &H2C + 4 fStream.Close()
|
|
|
|
|
|
|