flat assembler
Message board for the users of flat assembler.

Index > Projects and Ideas > let's build a LIBEVENT webserver without websocket + json

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
ok, revive this,
i think i wanna make it using libevent.
http://libevent.org/

step to build libevent dll using MinGW
http://obemsg.blogspot.com/2012/07/libevent-libevent-2-0-5dll-under.html

i will code some simple thing later, playing with libevent, hopefully it works.

maybe combine with libcurl dll, then do multithread libcurl send to multiple clients....
Post 09 Jul 2012, 11:04
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
f0dder wrote:
Why did you go for the WSAAsyncSelect model?

It might be relatively simple and all, but it's very poor performance (doesn't matter until you need many clients and/or high throughput, but then you'll regret your choice), and there's lots of situations where you don't need a GUI for a server app.


+1

I'd rather go with a non-GUI with a loop like so.

Code:
SOCKET client = NULL;
while(some_condition)
{
  listen();
  client = accept();
  if(client != NULL)
    if(!max_conn_reached)
       CreateThread(NULL,NULL,&serve_client,(LPVOID)client,NULL,&new_id);
}

int __stdcall serve_client(LPVOID param)
{
  SOCKET sock = (SOCKET)param;

 char * request =  socket_receive(sock), response = NULL;

 if(request != NULL)
    response = http_parse(request);

   if(response)
     { socket_send(sock,response); free(response); }
   else
     { socket_send(sock,some_internal_error); }

 if(request)
   free(request);
}
    


This is more of a C-pseudo code and untested.
Post 09 Jul 2012, 13:57
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
The response would probably need to be handled/sent by another http_xxx function. I.e, in case of chunked transfer e.t.c
Post 09 Jul 2012, 14:04
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
after a night, we got something half baked
i base it using the c code on this blog,
http://abhinavsingh.com/blog/2009/12/how-to-build-a-custom-static-file-serving-http-server-using-libevent-in-c/

i tried to use the evbuffer_add_file but failed Sad it hangs when i tried to use it through msvcrt _open


Last edited by sleepsleep on 24 Jul 2012, 23:12; edited 1 time in total
Post 21 Jul 2012, 20:36
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
i got a weird scenario, please advice,

i modify the C source to roughly exact my asm source then i compile it using mingw32 and it works, but the asm source after fasm doesn't works as expected, it hangs Sad

Code:
#include <stdlib.h>
#include <stdio.h>
#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
#include <string.h>
#include <fcntl.h>

#define LIBSRVR_SIGNATURE "libsrvr 0.01"
#define LIBSRVR_HTDOCS "D:/ACCESS"
#define LIBSRVR_INDEX "index.html"

struct evhttp *libsrvr;
struct event_base *libbase;
struct evbuffer *buffer;
struct evkeyvalq *headers;
int fp = -1;
char b1[1024];
int file_size;

void router(struct evhttp_request *r, void *arg) {
   sprintf(b1,"%s%s",LIBSRVR_HTDOCS, evhttp_request_get_uri(r));
     fprintf(stderr, "filename = %lu\n", b1);
 
    fp = open(b1,  O_RDONLY | O_BINARY) ;
       file_size = filelength(fp);
 buffer = evbuffer_new();

        headers = evhttp_request_get_output_headers(r);
     evhttp_add_header(headers, "Content-Type", "application/misc");
 evhttp_add_header(headers, "Server", LIBSRVR_SIGNATURE);
  evbuffer_add_file(buffer, fp, 0, file_size);
        evhttp_send_reply(r, HTTP_OK, "OK", buffer);
      evbuffer_free(buffer);
}

int main(int argc, char **argv) {
      int nresult;
        WSADATA wsadata;

        nresult = WSAStartup(MAKEWORD(2,2), &wsadata);

      libbase = event_base_new();
 libsrvr = evhttp_new(libbase);
      evhttp_set_gencb(libsrvr, router, NULL);
    evhttp_bind_socket(libsrvr, "0.0.0.0", 80);
       event_base_dispatch(libbase);

   return 0;
}
    

my makefile
Code:
ALL:SERVER.EXE
SERVER.EXE: SERVER.o
 gcc SERVER.o -o SERVER.EXE -L E:\CVS\libevent-2.0.19-stable\.libs -lmsvcrt -levent -lws2_32
SERVER.o: SERVER.c
        gcc -c -I E:\CVS\libevent-2.0.19-stable\include SERVER.c
    


my equivalent asm source
Code:
format PE console
include 'win32ax.inc'

CR                                                        = 13
LF                                                      = 10
_O_RDONLY                                       = 0
_O_BINARY                                        = 0x8000

.code
start:
invoke   WSAStartup,0202h,wsadata
            .if eax = 0
                 cinvoke event_base_new
                                      mov  [ebase],eax
                    cinvoke evhttp_new,[ebase]
                                  mov  [eserver],eax
                  cinvoke evhttp_set_gencb,[eserver], http.process.request, NULL
                      cinvoke evhttp_bind_socket,[eserver], '0.0.0.0', 80
                       cinvoke event_base_dispatch,[ebase]
         .endif
              mov  eax,0
          leave
               ret

proc http.process.request c request, arg
 cinvoke evhttp_request_get_uri,[request]
    cinvoke sprintf,buff_filetofind,"%s%s",static_dirpath,eax
 cinvoke _open,buff_filetofind,_O_RDONLY + _O_BINARY
                 mov  [efileh],eax
                   .if eax <> -1
                         cinvoke _filelength,[efileh]
                                                mov  [efilelen],eax
                         cinvoke sprintf,buff_filelen,'file len = %lu', [efilelen]
                         ccall   console,buff_filetofind
                             ccall   console,buff_filelen
                                cinvoke evbuffer_new
                                                mov  [ebuffer],eax
                          cinvoke evhttp_request_get_output_headers,[request]
                                         mov  [eheader],eax
                          cinvoke evhttp_add_header,[eheader],'Content-Type','application/misc'
                           cinvoke evhttp_add_header,[eheader],'Server','LIBSERVER'
                                cinvoke evbuffer_add_file,[ebuffer],[efileh],0,[efilelen]
                           cinvoke evhttp_send_reply,[request],200,"OK",[ebuffer]
                            cinvoke evbuffer_free,[ebuffer]
                     .endif
      ret
endp

proc console c string
    cinvoke sprintf,buff_console,<'%s',CR,LF,0>,[string]
        cinvoke printf,buff_console
 ret
endp

.data
static_dirpath      db 'D:/ACCESS',0

wsadata           WSADATA
ebase                dd 0
eserver         dd 0
ebuffer         dd 0
eheader         dd 0

efileh              dd 0
efilelen        dd 0

buff_filetofind     db 0fffh dup(0)
buff_console db 0fffh dup(0)
buff_filelen db 0ffh dup(0)

section '.idata' import data readable writeable
library      kernel32,       'kernel32.dll',\
         msvcrt,         'msvcrt.dll',\
           wsock32,        'wsock32.dll',\
          libevent,       'libevent-2-0-5.dll'

include 'API\KERNEL32.INC'
include 'API\MSVCRT.INC'
include 'API\WSOCK32.INC'
include 'API\LIBEVENT.INC'
    


Last edited by sleepsleep on 24 Jul 2012, 03:15; edited 1 time in total
Post 24 Jul 2012, 01:22
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17658
Location: In your JS exploiting you and your system
revolution
Using leave and ret to exit the main thread is not a good idea. Instead consider using invoke ExitProcess,0.

Also, is http.process.request supposed to be a C function?


Last edited by revolution on 24 Jul 2012, 02:38; edited 1 time in total
Post 24 Jul 2012, 02:29
View user's profile Send private message Visit poster's website Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
hi revolution,
i changed to
proc http.process.request c request, arg

but still doesn't work Sad
it just weird Sad idk where goes wrong....


update:
change start=30 in ur URL if you couldn't view latest post, it seems there is a size limit from http web server reply.


this solve the problem, lesson learned, next time must dig into C source & type, 1 argument doesn't mean 1 DWORD, it could be 64 bit
Code:
                    mov  eax,[efilelen]
                 cdq
                 push edx eax
                        push 0 0
    cinvoke evbuffer_add_file,[ebuffer],[efileh]
    


Last edited by sleepsleep on 24 Jul 2012, 23:10; edited 2 times in total
Post 24 Jul 2012, 02:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17658
Location: In your JS exploiting you and your system
revolution
Use a debugger.
Post 24 Jul 2012, 02:45
View user's profile Send private message Visit poster's website Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
Check the return type.

Libevent seems to be using __cdecl by default. You might want to find out by looking at the
Code:
evhttp_set_gencb(libsrvr, router, NULL)     


function definition. See if it's __stdcall or __cdecl
Post 24 Jul 2012, 02:53
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
Code:
void evhttp_set_gencb(struct evhttp *, void (*)(struct evhttp_request *, void *), void *);
    

i suppose it is cdecl (default for c source), there is no stdcall there.

typedef, the C source is working fine, the problem is the asm source.

if i comment this line (no hang)
Code:
cinvoke        evbuffer_add_file,[ebuffer],[efileh],0,[efilelen]
    


i guess the problem is due to ebp esp or ebx, but i couldn't figure out where it goes wrong Sad
Post 24 Jul 2012, 03:02
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
you wanna post the source and the other files so we can help you ?
Post 24 Jul 2012, 03:05
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
attached with the libevent dll & api INCLUDE


Description: libevent dll & api INCLUDE
Download
Filename: libevent.7z
Filesize: 351.37 KB
Downloaded: 356 Time(s)

Post 24 Jul 2012, 03:14
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
weird. I posted before revolution but his post is above mine.
Post 24 Jul 2012, 03:39
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
Image
Post 24 Jul 2012, 03:42
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
wait, i sent you the msvcrt.inc


Description:
Download
Filename: MSVCRT.7z
Filesize: 6.89 KB
Downloaded: 352 Time(s)

Post 24 Jul 2012, 03:45
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
I keep getting this
Quote:
[warn] Got a strange local ipv6 address ::


and then it quits.
Post 24 Jul 2012, 04:22
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
idk how you got that error?? is it antivirus or firewall message?

maybe you need to change 0.0.0.0 to 127.0.0.1 just in case, and change port number 80 if you are running some web http


Last edited by sleepsleep on 24 Jul 2012, 23:11; edited 1 time in total
Post 24 Jul 2012, 04:36
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
Yea. I forgot I have Apache server on.
It's running now. Let me check it
Post 24 Jul 2012, 06:03
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
using ollydbg to compare the c binary & my asm binary, i think we spot the problems,

from C binary
Code:
0040145C  |.  E8 63010000   CALL <JMP.&libevent-2-0-5.evhttp_add_header>      ; Jump to libevent-2-0-5.evhttp_add_header
00401461  |.  A1 A8544000   MOV EAX,DWORD PTR DS:[4054A8]
00401466  |.  99            CDQ
00401467  |.  8B1D 00204000 MOV EBX,DWORD PTR DS:[402000]
0040146D  |.  8B0D A0544000 MOV ECX,DWORD PTR DS:[4054A0]
00401473  |.  894424 10     MOV DWORD PTR SS:[LOCAL.6],EAX
00401477  |.  895424 14     MOV DWORD PTR SS:[LOCAL.5],EDX
0040147B  |.  C74424 08 000 MOV DWORD PTR SS:[LOCAL.8],0
00401483  |.  C74424 0C 000 MOV DWORD PTR SS:[LOCAL.7],0
0040148B  |.  895C24 04     MOV DWORD PTR SS:[LOCAL.9],EBX
0040148F  |.  890C24        MOV DWORD PTR SS:[LOCAL.10],ECX
00401492  |.  E8 35010000   CALL <JMP.&libevent-2-0-5.evbuffer_add_file>      ; Jump to libevent-2-0-5.evbuffer_add_file
    



compare with this asm binary
Code:
00401178  |.  FF15 68614000 CALL DWORD PTR DS:[<&libevent-2-0-5.evhttp_add_header>]    ; \libevent-2-0-5.evhttp_add_header
0040117E  |.  83C4 0C       ADD ESP,0C
00401181  |.  FF35 B2214000 PUSH DWORD PTR DS:[4021B2]
00401187  |.  6A 00         PUSH 0
00401189  |.  FF35 AE214000 PUSH DWORD PTR DS:[4021AE]
0040118F  |.  FF35 A2214000 PUSH DWORD PTR DS:[4021A2]
00401195  |.  FF15 54614000 CALL DWORD PTR DS:[<&libevent-2-0-5.evbuffer_add_file>]
    
Post 24 Jul 2012, 22:29
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 9128
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
phew,
i found the shit,

Code:
                   mov  eax,[efilelen]
                 cdq
                 mov  ebx,[efileh]
                   mov  ecx,[ebuffer]
                  push edx
                    push eax
                    push 0
                      push 0
                      push ebx
                    push ecx
    call    [evbuffer_add_file]
    

if i change below to above, it works,
Code:
cinvoke evbuffer_add_file,[ebuffer],[efileh],0,[efilelen]
    


hah...phewww

Code:
buffer.h
int evbuffer_add_file(struct evbuffer *outbuf, int fd, ev_off_t offset,
    ev_off_t length);

util.h
#ifdef WIN32
#define ev_off_t ev_int64_t
#else

#define ev_int64_t signed __int64
    


damn it.
Post 24 Jul 2012, 22:55
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.