• Welcome to Valhalla Legends Archive.
 

WS2_32!connect problems

Started by brew, November 20, 2007, 06:10 PM

Previous topic - Next topic

brew

For some reason, connect returns -1, and both GetLastError and WSAGetLastError return 10014, which according to msdn is:
Quote
WSAEFAULT
10014
The system detected an invalid pointer address in attempting to use a pointer argument in a call.
but i can't see what i'm doing wrong at all.
Here's my connect function:


SOCKET s;

bool ConnectSocket(const char *server, unsigned short port) {
WSADATA asdf;
struct sockaddr_in sdfsds;
//190h - WSAData struct
//1A0h - sockaddr_in struct
_asm {
lea eax, [ebp - 01A0h]
push 1A0h
push 0
push eax
call memset
add esp, 0Ch
cmp connected, 0
je _isnotconnected
// call DisconnectSocket
_isnotconnected:
lea ecx, [ebp - 0190h]
push ecx
push 0101h
call dword ptr [WSAStartup]
cmp eax, 0
jne _error
lea ecx, [ebp - 190h]
cmp word ptr [ecx], 0101h
jne _error
push IPPROTO_TCP
push SOCK_STREAM
push AF_INET
call dword ptr [socket]
mov s, eax
cmp eax, 0FFFFFFFFh
je _error
mov word ptr [ebp - 1A0h], AF_INET
push port
call dword ptr [htons]
mov word ptr [ebp - 19Eh], ax
push server
call dword ptr [inet_addr]
add esp, 4
mov dword ptr [ebp - 19Ch], eax
lea eax, [ebp - 1A0h]
push 10h
push eax
push s
call dword ptr [connect]
cmp eax, 0FFFFFFFFh
//call dword ptr [GetLastError] < ------ returns 10014
je _error
mov eax, 1
jmp _done
_error:
call dword ptr [WSACleanup]
xor eax, eax
_done:
mov esp, ebp
pop ebp
ret 8  
}
}
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

UserLoser


brew

Quote from: UserLoser on November 23, 2007, 02:58 AM
did you call WSAStartup?

Yes.
Quote
      lea ecx, [ebp - 0190h] // loads base address of the WSADATA struct into ecx
      push ecx //2nd parameter, LPWSADATA.
      push 0101h //1st parameter, Requested version. Winsock 1.1 is requested here
      call dword ptr [WSAStartup] //calls the API
      cmp eax, 0 //if WSAStartup was unsuccessful, it returns a nonzero value.
      jne _error //jump if flag was set.

Also, if i had failed to call WSAStartup first, wouldn't I be getting WSANOTINITIALISED (10093)?
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

UserLoser

why don't you do it the way you're supposed to do it instead of wasting time and confusing with inline assembly?

warz

or, at least code entirely in assembly. you get negative cool points for trying to look cool, but failing.

brew

Quote from: UserLoser on November 23, 2007, 02:06 PM
why don't you do it the way you're supposed to do it instead of wasting time and confusing with inline assembly?
Because msvc6 calls some function to check esp's value after every api call. It's really annoying. And i gain much more experience doing it this way, also it's more fun imo.
I've found an error, not really THE error though (add esp, 4 after the call to inet_addr, i probably got rid of a call to another function but forgot about that), and the same thing written in C fails as well.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

brew

Arrg, bs. I rewrote the entire function in C as close as i can, and it worked. Great, right? No.
Here's the disassembly from MSVC6's debugger:

183:      WSAStartup(0x0101, &asdf);
00401212 8B F4                mov         esi,esp
00401214 8D 85 70 FE FF FF    lea         eax,[ebp-190h]
0040121A 50                   push        eax
0040121B 68 01 01 00 00       push        101h
00401220 FF 15 C0 B2 41 00    call        dword ptr [__imp__WSAStartup@8 (0041b2c0)]
00401226 3B F4                cmp         esi,esp
00401228 E8 D1 02 00 00       call        _chkesp (004014fe)
184:      if (asdf.wVersion != 0x0101) goto blah_;
0040122D 0F B7 85 70 FE FF FF movzx       eax,word ptr [ebp-190h]
00401234 3D 01 01 00 00       cmp         eax,101h
00401239 74 05                je          ConnectSocket+62h (00401240)
0040123B E9 A3 00 00 00       jmp         done_+0Ah (004012e3)
185:      s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00401240 8B F4                mov         esi,esp
00401242 6A 06                push        6
00401244 6A 01                push        1
00401246 6A 02                push        2
00401248 FF 15 BC B2 41 00    call        dword ptr [__imp__socket@12 (0041b2bc)]
0040124E 3B F4                cmp         esi,esp
00401250 E8 A9 02 00 00       call        _chkesp (004014fe)
00401255 A3 28 46 41 00       mov         [s (00414628)],eax
186:      if (s == INVALID_SOCKET) goto blah_;
0040125A 83 3D 28 46 41 00 FF cmp         dword ptr [s (00414628)],0FFh
00401261 75 02                jne         ConnectSocket+87h (00401265)
00401263 EB 7C                jmp         done_+8 (004012e1)
187:      sckaddr.sin_family = AF_INET;
00401265 66 C7 85 60 FE FF FF mov         word ptr [ebp-1A0h],offset ConnectSocket+8Eh (0040126c)
188:      sckaddr.sin_port = htons(port);
0040126E 8B F4                mov         esi,esp
00401270 FF 75 0C             push        dword ptr [ebp+0Ch]
00401273 FF 15 B8 B2 41 00    call        dword ptr [__imp__htons@4 (0041b2b8)]
00401279 3B F4                cmp         esi,esp
0040127B E8 7E 02 00 00       call        _chkesp (004014fe)
00401280 66 89 85 62 FE FF FF mov         word ptr [ebp-19Eh],ax
189:      sckaddr.sin_addr.S_un.S_addr = inet_addr(server);
00401287 8B F4                mov         esi,esp
00401289 FF 75 08             push        dword ptr [ebp+8]
0040128C FF 15 B4 B2 41 00    call        dword ptr [__imp__inet_addr@4 (0041b2b4)]
00401292 3B F4                cmp         esi,esp
00401294 E8 65 02 00 00       call        _chkesp (004014fe)
00401299 89 85 64 FE FF FF    mov         dword ptr [ebp-19Ch],eax
190:      if (connect(s, (const struct sockaddr *)&sckaddr, sizeof(struct sockaddr_in)) == INVALID_SOCKET) goto blah_;
0040129F 8B F4                mov         esi,esp
004012A1 6A 10                push        10h
004012A3 8D 85 60 FE FF FF    lea         eax,[ebp-1A0h]
004012A9 50                   push        eax
004012AA FF 35 28 46 41 00    push        dword ptr [s (00414628)]
004012B0 FF 15 B0 B2 41 00    call        dword ptr [__imp__connect@12 (0041b2b0)]
004012B6 3B F4                cmp         esi,esp
004012B8 E8 41 02 00 00       call        _chkesp (004014fe)
004012BD 83 F8 FF             cmp         eax,0FFh
004012C0 75 02                jne         ConnectSocket+0E6h (004012c4)
004012C2 EB 1B                jmp         done_+6 (004012df)
191:      goto done_;
004012C4 EB 17                jmp         done_+4 (004012dd)
192:  blah_:
193:      WSACleanup();
004012C6 8B F4                mov         esi,esp
004012C8 FF 15 AC B2 41 00    call        dword ptr [__imp__WSACleanup@0 (0041b2ac)]
004012CE 3B F4                cmp         esi,esp
004012D0 E8 29 02 00 00       call        _chkesp (004014fe)
194:      return false;
004012D5 32 C0                xor         al,al
004012D7 EB 0C                jmp         done_+0Ch (004012e5)
195:  done_:
196:      return true;
004012D9 B0 01                mov         al,1
004012DB EB 08                jmp         done_+0Ch (004012e5)
197:  }


which, if you look at the original code that I wrote, is almost EXACTLY the same with the exception of the esp checking, and a few quirks (note the last two lines, they modify the low bit alone for some reason. I find that kind of odd, is this an optimization?)
What is it doing so different that it's working! I can't find it.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Maddox

Try making your function naked and specify a calling convention.
asdf.