C ++奇怪的memcpy行为

时间:2016-10-20 10:53:31

标签: c++ winsock memcpy

对于CTF,我尝试构建一个易受缓冲区溢出影响的WinSock应用程序,但至少对我来说,我遇到了一个非常奇怪的memcpy行为。视觉工作室中的所有安全措施都已被禁用。

--drop table Employee
--drop table Dept

create table dbo.[Employee](
  EmpId int not null identity primary key
, EmpName varchar(300) not null
, MgrId int null
, DeptId int not null
, Salary decimal(12,2) not null
)

create table dbo.[Dept](
  DeptId int not null identity primary key
, DeptName varchar(300)  not null
)
GO

alter table dbo.[Employee]  with check add constraint [FK_Employee_Dept] foreign key([DeptId])
references dbo.[Dept] ([DeptId])
GO

alter table dbo.[Employee] check constraint [FK_Employee_Dept]
GO

insert into dbo.[Dept] (DeptName)
values
 ('Dep IT')
,('Dep HR')

GO

--select * from dbo.[Dept]

insert into dbo.[Employee] (EmpName, MgrId, DeptId, Salary)
values
 ('Irwin', null, 1, 15000.99)
,('Iavin Prime', 1, 1, 4000.33)
,('Iavin IV', 2, 1, 3000.33)
,('New It guy', 1, 1, 1000.33)

,('Hermann', null, 2, 15000.99)
,('Holland', 5, 2, 4000.33)

GO

-- List dept and employees orderred by dept and salary
select dp.DeptName, ep.EmpName, ep.Salary
from dbo.Dept dp
join dbo.Employee ep on ep.DeptId = dp.DeptId
order by dp.DeptName, ep.Salary desc

-- pick highest salary by dept
select dp.DeptId, max(ep.Salary)
from dbo.Dept dp
join dbo.Employee ep on ep.DeptId = dp.DeptId
group by dp.DeptId

-- pick alle employee from each dept with matches the highest salary/dep
select dp.DeptName, ep.EmpName, ep.Salary
from dbo.Dept dp
join dbo.Employee ep on ep.DeptId = dp.DeptId
join (
        select dp.DeptId, max(ep.Salary) as TopSalary
        from dbo.Dept dp
        join dbo.Employee ep on ep.DeptId = dp.DeptId
        group by dp.DeptId
) as tsd on tsd.DeptId = ep.DeptId and ep.Salary = tsd.TopSalary

正如您从上面的代码片段中看到的,这是一个非常简单的应用程序,只回复收到的字节。现在我有两个关于memcpy行为的问题:

  1. 为什么这不会触发缓冲区溢出?在我看来,我试图将一个1024字符长的缓冲区复制到300个字符长的缓冲区。当使用char *尝试相同时,它会触发缓冲区溢出。

  2. iSendResult = send(ClientSocket,sendbuf,sizeof(sendbuf),0); 当我将大小更改为iResult(这是接收的字节总数)时,应用程序会正确回答收到的所有字符,但我选择发送的sendbuf只有300个字符长,他从哪里获取剩余的字符(某种临时缓冲区?)

  3. 所以这些是我不确定如何解释的两种行为。 如果有人能够对此有所了解,那将是很好的。

    祝你好运!

1 个答案:

答案 0 :(得分:2)

你正在溢出缓冲区。 您期望发生什么?缓冲区溢出是一种未定义的行为。在一个非常简单的程序中,未定义的行为习惯于正常工作。这就是使未定义的行为如此阴险的原因。

当你的程序运行时,它会将300字节写入sendbuf,其余字节写入内存中的sendbuf之后的任何内容。我的猜测是recvbuflen包含字节300到304.如果在char unused[1024] = {0}之后添加一个新变量sendbuf,您可以通过检查字节的内容来查看字节的写入位置。 memcpy