Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Keyen Night

#321
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 :xD

 
Código (vb.net) [Seleccionar]
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

#322
Hay una clase del mismo Vb.net llamada ClipBoard o My.Computer.ClipBoard, revisala tiene todo lo que necesitas que tenga que ver con Copy&Paste de Windows.
#323
Con respecto a la segunda forma que dijistes te refieres a inyección de DLL o a otra forma de hacer el hook inyectando código?
#324
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
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 :-X 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)
Código (c++) [Seleccionar]

#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)
Código (c++) [Seleccionar]

#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
sprintf(dat.mensaje,"Mensaje");
sprintf(dat.titulo,"Texto");

//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();
system("pause>nul");
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;
}
#326
La mejor opción realmente es la lista dinámica.
#327
Cada vez más rápido y con más soporte para números más grandes :laugh:

Quizás a alguien le sirva ;D 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.

Código (vb.net) [Seleccionar]
   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)

       Factorize = New 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 :xD

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.
#328
Disculpa por el doble post :-[ Gracias por la recomendación.
#329
No se si sea la forma más facil pero así calcule el offset de #strings XD
Código (vb.net) [Seleccionar]

                    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()
#330
Más descriptivo el titulo es imposible :laugh: como puedo obtener el offset y el size de la tabla de metada #strings en un assembly de .net?, creo que tiene que ver con el ManifestModule al cargar un assembly pero no tengo nada concreto...